CPP unordered_set只使用比较器而不是哈希
cpp unordered_set just use comparator not hash
#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<b为真,b><a也是真的,那么这个元素将无法成功插入,有时,很难提供顺序。>
如果有人能帮忙,非常感谢
编辑: 我的目的是让两个边称为 e1,e2,如果(e1.a1==e2.a1&&e1.a2==e2.a2)
或(e1.a1==e2.a2 && e1.a2==e2.a1)
,它们与我提供的相同 在结构体中。 但是当我测试时。哈希函数似乎也可以改变比较。有人说我定义哈希和比较器的方式会导致未定义的行为。 这是真的吗?为什么? 如果是真的,如何解决这个问题?我只想让比较器决定哪一个满意地插入unordered_set而不重复。而且真的不在乎哈希。
顺便说一句,感谢很多人的回复
如果要互换处理edge.a1
和edge.a2
,则必须实现一个哈希函数,即使它们被交换,也返回相同的值。我建议不要使用加法,因为加法对于浮点数可能不是可交换的,但您可以按大小对它们进行排序,然后合并哈希:
struct hash {
size_t operator()(const edge& e1) const {
auto h1 = std::hash<float>{}(std::min(e1.a1, e1.a2));
auto h2 = std::hash<float>{}(std::max(e1.a1, e1.a2));
return h1 ^ (h2 << 1)
};
};
这只对相当大的浮点数集有意义,因为否则哈希开销可能首先超过使用哈希数据结构的好处。
旧答案供参考:
具有相同哈希值的对象在
unordered_set
.它们只是存储在同一个存储桶中。有一个KeyEqual
用于比较的模板参数,其通过 默认使用Key
的operator==
。所以你的主要问题是,comp
应该实现e1 == e2
而不是e1 < e2
(并且应该 可能被称为equal
(。哈希仅用于加快搜索、插入和删除的速度 的元素。
另一方面,您可能希望使用成员的哈希值 变量而不是值本身来计算哈希
edge
:struct hash { size_t operator()(const edge& e1) const { auto h1 = std::hash<float>{}(e1.a1); auto h2 = std::hash<float>{}(e1.a2); return h1 ^ (h2 << 1) }; };
这样,您就不会为交换的两个边缘获得相同的哈希值 坐标。这里建议使用这种组合哈希的方式(但是 不是组合两个以上的好方法(。
您不必使用edge
的成员来提供哈希。仅要求相等的值具有相等的哈希值。"始终有效"哈希是
struct hash{
size_t operator()(const edge& e1) const {
return 0;
};
};
但似乎你最初的尝试更好
struct hash{
size_t operator()(const edge& e1) const {
return std::hash<float>{}(e1.a1 + e1.a2); // + is commutative
};
};
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 使用Qt C++计算类似Git的SHA1哈希
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- CPP unordered_set只使用比较器而不是哈希
- 将私有结构哈希器运算符转换为静态
- boost SHA1 哈希与 md5sum/sha1sum 的运行时比较
- 迭代器关系运算符出错(带单独链接和迭代器的自定义哈希表)
- 来自并发哈希映射的迭代器是否安全
- 如何将单个字符转换为为基本密码哈希器设置整数,C++
- Win32 MD5哈希器的奇怪行为
- C :在哈希地图中计数平等比较的数量
- 声明具有免费功能的Unordered_set,以用于用户定义的哈希和比较
- hash_set哈希器函数
- 比较sha1哈希是否相等的最佳方式
- 我如何计算比较的次数?(哈希表)
- 哈希函数用于6个整数的良好排序/比较
- 返回c++哈希表代码中的空迭代器
- (C++) 无法迭代密钥哈希器函数中的向量
- Tbb 并发哈希映射迭代器