对象<int,int =“”> </int,>的向量的哈希函数

时间:2014-05-25 20:51:03

标签: c++ vector hash

我正在尝试为矢量&lt;实现 unordered_map 对&lt; INT,INT&GT;取代。自there's no such default hash function以来,我试图想象一下我自己的功能:

struct ObjectHasher
{
  std::size_t operator()(const Object& k) const
  {
    std::string h_string("");
    for (auto i = k.vec.begin(); i != k.vec.end(); ++i)
    {
      h_string.push_back(97+i->first);
      h_string.push_back(47); // '-'
      h_string.push_back(97+i->second);
      h_string.push_back(43); // '+'
    }
    return std::hash<std::string>()(h_string);
  }
};

主要思想是将整数列表改为((97,98),(105,107))到格式化字符串中,如“a-b + ik” 并通过哈希&lt;计算其哈希值string&gt;()。我选择97,48和43号码只是为了让我在测试期间能够在终端中轻松显示哈希字符串。

我知道这种功能可能是一个非常幼稚的想法,因为一个好的哈希函数应该强对抗冲突。好吧,如果给push_back()的整数大于255,我不知道会发生什么......那么,您如何看待以下问题:

  • (1)我的函数可以用于大整数吗?
  • (2)我的功能适用于所有环境/平台吗?
  • (3)我的函数太慢而不能成为哈希函数?
  • (4)......你还有什么更好的吗?

3 个答案:

答案 0 :(得分:4)

你需要的只是一个“哈希”整数的函数。你可以从boost中窃取这样一个函数:

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

现在你的功能很简单:

struct ObjectHasher
{
  std::size_t operator()(const Object& k) const
  {
    std::size_t hash = 0;
    for (auto i = k.vec.begin(); i != k.vec.end(); ++i)
    {
      hash_combine(hash, i->first);
      hash_combine(hash, i->second);
    }
    return hash;
  }
};

答案 1 :(得分:2)

与其他哈希函数相比,此函数可能非常慢,因为它使用动态内存分配。另外std::hash<std::string>不是很好的哈希函数,因为它非常通用。对所有整数进行XOR并使用std::hash<int>可能会更好。

答案 2 :(得分:1)

这是一个非常有效的解决方案。所有哈希函数都需要一个字节序列,通过将元素连接在一起作为字符串,您将提供地图的唯一字节表示。

当然,如果您的地图包含大量项目,这可能会变得难以驾驭。