【问题标题】:Fast hash for std::set<int> of two values?两个值的 std::set<int> 的快速散列?
【发布时间】:2011-04-07 12:31:18
【问题描述】:

我使用 std::set&lt;int&gt; 作为标准映射 (std::unordered_map&lt;std::Set&lt;int&gt;,float&gt;) 的键。我需要这个集合的哈希值。

集合总是只有两个整数,其值最多可达 200 万。

对于像性能这样关键的键,有什么好的快速散列的想法吗?

【问题讨论】:

  • 我理解正确吗?您正在使用std::set 作为TR1:unordered_map 的密钥?
  • 如果只有两个整数,为什么不用std::pair&lt;int, int&gt;作为key呢?
  • 我认为如果我使用一对,就我的目的而言,我会遇到问题 (a,b) == (b,a) 但如果使用一对这将不是真的(我假设) .当我使用集合时,因为整数是排序的,所以我在查找时不会意外错过地图中的任何值
  • 无论如何,据我所知,整数对没有内置哈希函数,所以问题不是差不多吗?
  • 好又快的哈希?按位|^?由于您使用的是集合,因此您可以通过位移第一个值或与不同的种子异或来做一些愚蠢的事情......但散列函数往往取决于值的底层分布。

标签: c++ stl hash map set


【解决方案1】:

您可以使用 boost::hash_combine() :http://www.boost.org/doc/libs/1_44_0/doc/html/hash/combine.html

【讨论】:

    【解决方案2】:

    您没有准确说明查找的目的是什么, 但也许你应该(或不应该):

    • 只需使用 struct { int a, b; } 作为键 - 您控制成员的插入(确保 a &lt;= b

    • 使用Sparse Matrix 实现

    问候

    rbo

    【讨论】:

      【解决方案3】:

      我会放弃既定的想法(将两个整数存储在std::set 中既浪费内存又浪费时间)并使用这对。然后定义

      template <class A>
      struct unordered_pair_hash
      {
        std::size_t operator()(const std::pair<A, A>& p) const { 
          using std::min;
          using std::max;
          return std::hash<A>()(min(p.first, p.second))+
              17*std::hash<A>()(max(p.first, p.second));
        }
      };
      
      template <class A>
      struct unordered_pair_eq
      {
        bool operator()(const std::pair<A, A>& p1, const std::pair<A, A>& p2) const {
          using std::min;
          using std::max;
          return min(p1.first, p1.second)==min(p2.first, p2.second) &&
                 max(p1.first, p1.second)==max(p2.first, p2.second);
        }
      };
      

      然后使用自定义哈希和相等性声明地图。

      std::unordered_map<std::pair<int, int>, float, unordered_pair_hash<int>, unordered_pair_eq<int> > ...
      

      【讨论】:

      • 为什么 17 作为第二个值的倍数?
      • 更简单的哈希函数:std::hash&lt;A&gt; hash; return hash(p.first) + hash(p.second);。当需要交换性时,无符号加法是一个很好的哈希组合器(在这种情况下,因为 {1,0}{0,1} 需要哈希到相同的值)。
      猜你喜欢
      • 1970-01-01
      • 2017-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-30
      • 1970-01-01
      • 2011-12-10
      • 1970-01-01
      相关资源
      最近更新 更多