对一对整数(pair<int, int>)向量的哈希函数

hash function for a vector of pair<int, int>

本文关键字:int 向量 哈希 函数 整数 pair      更新时间:2023-10-16

我试图实现一个unordered_map为一个矢量<一对&>>。由于没有这样的默认哈希函数,我试着想象一个我自己的函数:

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+i-k",并通过hash &lt计算其哈希值;字符串>()。我选择了97、48和43这三个数字,只是为了在测试过程中方便地在终端上显示散列字符串。

我知道这种函数可能是一个非常幼稚的想法,因为一个好的哈希函数应该是快速强对抗碰撞。嗯,如果给push_back()的整数大于255,我不知道会发生什么……那么,你觉得下面的问题怎么样?
  • (1)是我的函数ok大整数?
  • (2)我的功能是否适用于所有环境/平台?
  • (3)我的函数太慢,不能作为哈希函数吗?
  • (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;
  }
};

与其他散列函数相比,这个函数可能非常慢,因为它使用动态内存分配。std::hash<std::string>也不是一个很好的哈希函数,因为它很一般。对所有int进行异或并使用std::hash<int>可能更好。

这是一个完全有效的解决方案。哈希函数所需要的只是一个字节序列,通过将元素连接在一起作为字符串,您提供了映射的唯一字节表示。

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