【发布时间】:2020-03-28 02:05:50
【问题描述】:
#include <unordered_set>
#include <iostream>
class edge{
public:
float a1;
float a2;
};
struct comp{
bool operator()(const edge& e1, const edge& e2) const {
return true;
return (
(e1.a1==e2.a1 && e1.a2==e2.a2) ||
(e1.a1==e2.a2 && e1.a2==e2.a1)
);
};
};
struct hash{
size_t operator()(const edge& e1) const {
// return std::hash<float>()(e1.a1+e1.a2);
return std::hash<float>()(e1.a1+e1.a2*2);
};
};
int main() {
std::unordered_set<edge,hash,comp> s1;
s1.insert(edge{1.1,2.2});
s1.insert(edge{2.2,1.1});
for( auto& it : s1 ) {
std::cout << it.a1 << " " << it.a2 << "\n";
}
std::cout << "s1.size " << s1.size() << "\n";
}
我意识到如果不同的元素具有相同的哈希值,那么它们被认为是相等的,但我只是希望这个 unordered_set 使用我定义的比较器,只是忽略哈希?
如何实现?
我知道我可以使用set,但是使用set需要考虑顺序,如果a
如果有人能帮忙,不胜感激
编辑:
我的意图是让两条边称为 e1,e2,如果 (e1.a1==e2.a1&&e1.a2==e2.a2)or(e1.a1==e2.a2 && e1.a2==e2.a1) 如我提供的那样,它们是相同的
在结构比较中。
但是当我测试时。似乎哈希函数也可以改变比较。有人说我定义哈希和比较器的方式会导致未定义的行为。
真的吗?为什么?
如果是真的,如何解决这个问题?我只想让比较器决定将哪一个满足插入 unordered_set 而不重复。而且真的不关心哈希。
顺便说一句,感谢很多人回复
【问题讨论】:
-
std::unordered_multiset符合您的要求吗? -
如果您使用
std::tie,订购通常并不难。 -
你的意图是拥有
size() == 1? -
“我意识到如果不同的元素具有相同的哈希值,那么它们被认为是相等的” - 不正确。无序集散列+比较器的要点是提供恒定时间散列和线性子时间(k)比较。 unordered_set 仍然是 set (很疯狂,对吧?)。元素是独一无二的。该唯一性是通过
hash在当前哈希表中找到正确的碰撞桶,然后通过compare在碰撞桶中搜索匹配元素来确定的。如果这不是您想要的行为,那么就不要再尝试将方形钉子塞进圆孔中了;使用不同的容器。 -
我相信比较哈希并不比比较一对
floats快多少。无论如何,你的哈希看起来有点弱。所以我会考虑改用std::set。