良好的哈希函数超过C++ unordered_set
Good hash function over C++ unordered_set
我希望在C++ std::unordered_set<char>
上实现哈希函数。我最初尝试使用boost::hash_range:
namespace std
{
template<> struct hash<unordered_set<char> >
size_t operator(const unordered_set<char> &s)(
{
return boost::hash_range(begin(s), end(s))
};
}
但后来我意识到,因为集合是无序的,迭代顺序不稳定,因此哈希函数是错误的。对我来说有什么更好的选择?我想我可以std::set
而不是std::unordered_set
,但是使用有序集合只是因为它更容易散列似乎......错。
一个非常相似的问题,尽管是在 C# 中,但在这里被问到:
列表中的哈希函数与其中项目的顺序无关
在那边,Per给出了一个很好的独立于语言的答案,应该会让你走上正确的轨道。简而言之,对于输入
x1, ..., xn
您应该将其映射到
f(x1) op ...OP F(xn)
哪里
- f 是单个元素的良好哈希函数(在您的情况下为整数)
- OP 是一个交换运算符,例如 XOR 或 Plus
散列一个整数一开始可能毫无意义,但你的目标是使两个相邻的整数彼此不同,这样当与 op 结合使用时不会产生相同的结果。 例如,如果使用 + 作为运算符,则希望 f(1)+f(2) 给出与 f(0)+f(3) 不同的结果。
如果标准哈希函数不适合 f 并且您找不到,请查看链接的答案以获取更多详细信息......
您可以尝试简单地添加与顺序无关的内容并返回其哈希值:
template<> struct hash<unordered_set<char> >
size_t operator(const unordered_set<char> &s) {
long long sum{0};
for ( auto e : s )
sum += s;
return std::hash(sum);
};