良好的哈希函数超过C++ unordered_set

Good hash function over C++ unordered_set

本文关键字:C++ unordered set 哈希 函数      更新时间:2023-10-16

我希望在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给出了一个很好的独立于语言的答案,应该会让你走上正确的轨道。简而言之,对于输入

x

1, ..., 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);
};