2016-09-01 130 views
2

我必须编写一个散列函数,以便我可以将std::pair<int,std::string>放入unordered_set散列字符串和int在一起?

关于输入:

  1. 将被散列的串是非常小的(1-3字母长度)。
  2. 同样,整数将是小号的无符号数(远小于无符号整数的极限)。

是否有意义使用字符串的散列(作为数字),并且只使用Cantor的枚举对来生成“新”散列?

由于为std::string的“内置”哈希函数应该是一个体面的哈希函数...

struct intStringHash{ 
    public: 
     inline std::size_t operator()(const std::pair<int,std::string>&c)const{ 
      int x = c.first; 
      std::string s = c.second; 
      std::hash<std::string> stringHash; 
      int y = stringHash(s); 

      return ((x+y)*(x+y+1)/2 + y); // Cantor's enumeration of pairs 
     } 
    }; 
+1

您可以'提振:: hash_combine',或者,如果你不能使用升压出于某种原因,检查他们做了什么,并复制 – milleniumbug

+0

我不能使用boost代码。你能解释一下怎么做吗?我读过另一篇关于创建函数的帖子http://stackoverflow.com/questions/2590677/how-do-i-combine-hash-values-in-c0x,但我不知道如何使用它关于我的上面的函数? –

回答

5

boost::hash_combine是创建哈希一个简单的方法:即使你不能使用Boost,功能相当简单,所以它是trivial to copy the implementation

用法示例:

struct intStringHash 
{ 
public: 
    std::size_t operator()(const std::pair<int, std::string>& c) const 
    { 
     std::size_t hash = 0; 
     hash_combine(hash, c.first); 
     hash_combine(hash, c.second); 
     return hash; 
    } 
}; 
3

是的,你会生成您有一个哈希函数每种类型的哈希值。

是很正常的异或哈希把它们混合起来:

int hash1; 
int hash2; 

int combined = hash1^hash2; 
+0

你能解释为什么它的正常? –

+0

为了性能和简洁,通常使用这种方法来组合散列。如果每个散列函数都很好(低冲突率),则使用* exclusive或*组合散列的结果通常是好的(低冲突率)。毕竟,它看起来并不像你在做任何与安​​全有关的事情,或者创建一个最小的完美哈希函数。 – keith