【问题标题】:Hash function for a pair of long long?哈希函数为一对long long?
【发布时间】:2010-10-18 19:01:23
【问题描述】:

我需要将一对long long 映射到double,但我不确定要使用什么哈希函数。每对可能由任意两个数字组成,尽管实际上它们通常是介于0 和大约100 之间的数字(但同样不能保证)。

Heretr1::unordered_map 文档。我是这样开始的:

typedef long long Int;
typedef std::pair<Int, Int> IntPair;

struct IntPairHash {
  size_t operator(const IntPair& p) const {
    return ...; // how to hash the pair?
  }
};

struct IntPairEqual {
  bool operator(const IntPair& a, const IntPair& b) const {
    return a.first == b.first 
      && a.second == b.second;
  }
};

tr1::unordered_map<IntPair, double, IntPairHash, IntPairEqual> myMap;

一般来说,我永远不确定要使用什么哈希函数。什么是好的通用哈希函数?

【问题讨论】:

标签: c++ hash tr1 unordered-map hash-function


【解决方案1】:

散列一对的自然方法是以某种方式组合其组件的散列。最简单的方法就是使用 xor:

namespace std {
namespace tr1 {

template<typename a, typename b>
struct hash< std::pair<a, b> > {
private:
   const hash<a> ah;
   const hash<b> bh;
public:
   hash() : ah(), bh() {}
   size_t operator()(const std::pair<a, b> &p) const {
      return ah(p.first) ^ bh(p.second);
   }
};

}} // namespaces

请注意,这会将 (1,1) 或 (2,2) 之类的哈希对全部归零,因此您可能需要使用一些更复杂的方法来组合各个部分的哈希,具体取决于您的数据。 Boost 做了这样的事情:

size_t seed = ah(p.first);
return bh(p.second) + 0x9e3779b9 + (seed<<6) + (seed>>2);

【讨论】:

  • 请仔细阅读 boost hash.hpp。 Bost 做了这样的事情:seed = hash(first) + 0x9e3779b9 + (seed>2);返回种子 ^ (hash(second) + 0x9e3779b9 + (seed>2));
【解决方案2】:

boost::hash 形成函数库。

或自己编写。最简单的版本 = pair.first * max_second_value + pair.second

【讨论】:

    【解决方案3】:

    一个建议:看看这个 SO 帖子:"I don't understand std::tr1::unordered_map"

    另外,Equality Predicates and Hash Predicates 上的 Boost 文档也是一个好地方(还有这个 example)。

    【讨论】:

      【解决方案4】:

      您真的需要基于哈希的地图吗?基于二叉树的一般映射只要复杂性保证它可以解决您要解决的问题,就可以正常工作。

      【讨论】:

      • 嗯好吧,在这种情况下,比较两个 IntPair 的 Compare 函数会是什么样子(IntPair 的 less 函数)?
      • @Frank:最简单的形式:(a.first
      • 这个 (a.first
      • @Frank:它们都定义了一个顺序,只是它们不同。我更喜欢“@dribeas”版本,它看起来更合乎逻辑(但稍微贵一点)
      • @Framk, @Martin: (a.first &lt; b.first) &amp;&amp; (a.second &lt; b.second) 不是排序。对 (1,0) 和 (0,1) 在这种“排序”中是不同且不可比较的。
      猜你喜欢
      • 2021-01-20
      • 2013-07-29
      • 2023-03-29
      • 2011-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-18
      相关资源
      最近更新 更多