C++ 一个很好的向量散列函数

C++ 一个很好的向量散列函数,c++,c++11,hash,C++,C++11,Hash,我有一些整数向量,我想在c++11中有效地存储在无序的_映射中。我的问题是: 如何最好地存储这些信息并优化。查找查询 我提出了以下哈希值: class uint32_vector_hasher { public: std::size_t operator()(std::vector<uint32_t> const& vec) const { std::size_t ret = 0; for(auto& i : vec) { ret ^=

我有一些整数向量,我想在c++11中有效地存储在无序的_映射中。我的问题是:

如何最好地存储这些信息并优化
。查找
查询

我提出了以下哈希值:

class uint32_vector_hasher {
public:
  std::size_t operator()(std::vector<uint32_t> const& vec) const {
    std::size_t ret = 0;
    for(auto& i : vec) {
      ret ^= std::hash<uint32_t>()(i);
    }
    return ret;
  }
};
类uint32\u向量\u散列器{ 公众: std::size\u t运算符()(std::vector const&vec)const{ 标准:尺寸=0; 用于(自动和输入:vec){ ret^=std::hash()(i); } 返回ret; } };
然后将这些对象存储在一张无序的地图中。不过,我有几个问题要问

  • 散列计算的频率是多少,只有一个,一些随机数或次数
  • 使用
    ==
    和散列函数创建包装器对象是否有意义,以便记忆散列并避免多次计算

  • 在分析时,我注意到我的大量cpu时间都花在查找无序的地图上,这并不是最理想的:(

    尽可能与专家一起:
    因此,当不想使用boost时,Michael Blur的评论导致了以下哈希函数实现:

    std::size_t operator()(std::vector<uint32_t> const& vec) const {
      std::size_t seed = vec.size();
      for(auto& i : vec) {
        seed ^= i + 0x9e3779b9 + (seed << 6) + (seed >> 2);
      }
      return seed;
    }
    
    std::size\u t操作符()(std::vector const&vec)const{
    std::size_t seed=vec.size();
    用于(自动和输入:vec){
    seed^=i+0x9e3779b9+(seed>2);
    }
    返回种子;
    }
    

    似乎有效。

    每次插入和每次查找都会进行一次哈希运算,每次调整基础表的大小时都可能对每个对象进行一次哈希运算。为了澄清这一点,系统不会对表中已经存在的内容进行哈希运算,只是因为您正在查找某个内容,而只是对用于查找的键进行哈希运算。顺便说一句,xor是一个可怕的错误hash combiner@RichardPlunkett关于xor是一个糟糕的组合器的评论的一些扩展示例:如果两个向量具有相同的数据,但顺序不同,它们将具有相同的哈希。如果一个向量具有多个相同的值,则这些值中的大多数将不会考虑到组合哈希中(它们相互抵消)。如果值通常很小(或者更确切地说,不使用
    uint32\u t
    中的全范围位)那么最重要的位就不会用在组合哈希中。@Martin,sort不太可能有帮助,只不过它意味着一个特别糟糕的例子不会出现,还有很多其他的例子。你知道最近版本的链接已经失效了吗?尽管boost是一个很好的库,但我还是有点不愿意使用它,因为我的软件需要在平台的真实性。@MartinKristiansen:boost也适用于各种平台。即使您不想或不能使用boost,@RichardPlunkett指向的
    hash_combine()
    函数也只是一行:
    seed^=hash_值(v)+0x9e3779b9+(seed>2)
    @MartinKristiansen是公式数字中的神奇数字,理论上得到了证实吗?@Orient看,这是一个开始种子。它会很快被异或运算(
    ^=
    )变异。
    vec.size()
    (第2行)可能会更好,因为它考虑了更多的向量信息。我已经调整了回复。