如何正确地散列自定义结构?

aby*_*s.7 6 c++ hash probability

在C++语言有默认的哈希函数模板std::hash<T>的最简单的类型,如std::string,int等我想,这些功能有很好的熵和相应的随机变量的分布是均匀的统计.如果不是,那么让我们假装它是.

然后,我有一个结构:

struct CustomType {
  int field1;
  short field2;
  string field3;
  // ...
};
Run Code Online (Sandbox Code Playgroud)

我想哈希它,使用其中一些字段的单独哈希,比方说,std::hash(field1)std::hash(field2).两个哈希都在一组可能的类型值中size_t.

什么是好的哈希函数,可以将这些结果组合并将它们映射回来size_t

Yuu*_*shi 8

boost::hash_combine 是可以帮助你的东西:

namespace std
{
template <>
struct hash<CustomType>
{
    std::size_t operator()(const CustomType& c) const
    {
        std::size_t result = 0;
        boost::hash_combine(result, field1);
        boost::hash_combine(result, field2);
        return result;
    }
};
}
Run Code Online (Sandbox Code Playgroud)

请参阅此处的 boost 文档。


P0W*_*P0W 5

boost::hash_combine 哈希不同的领域是一个非常好的人.

如果您没有boost库,可以使用:

template <class T>
inline void hash_combine(std::size_t & s, const T & v)
{
  std::hash<T> h;
  s^= h(v) + 0x9e3779b9 + (s<< 6) + (s>> 2);
}

 struct S {
  int field1;
  short field2;
  std::string field3;
  // ...
};

template <class T>
class MyHash;

template<>
struct MyHash<S>
{
    std::size_t operator()(S const& s) const 
    {
        std::size_t res = 0;
       hash_combine(res,s.field1);
       hash_combine(res,s.field2);
       hash_combine(res,s.field3);
        return res;
    }
};
Run Code Online (Sandbox Code Playgroud)

然后可能 std::unordered_set<S> s;等等

  • 阅读[boost::hash_combine中的幻数](http://stackoverflow.com/q/4948780/1870232) (2认同)