根据个人经验,我知道这有效并产生良好的分布.(抄袭http://www.cse.yorku.ca/~oz/hash.html):
djb2
这个算法(k = 33)是多年前dan bernstein在comp.lang.c中首次报道的.该算法的另一个版本(现在bernstein青睐)使用xor:hash(i)= hash(i-1)*33 ^ str [i]; 33号的神奇之处(为什么它比许多其他常数(优质或非常)效果更好)从未得到充分的解释.
unsigned long hash(unsigned char *str) {
unsigned long hash = 5381;
int c;
while (c = *str++) {
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
}
return hash;
}
Run Code Online (Sandbox Code Playgroud)
重新提出第一个问题,例如:
int hash = 0;
int offset = 'a' - 1;
for(string::const_iterator it=s.begin(); it!=s.end(); ++it) {
hash = hash << 1 | (*it - offset);
}
Run Code Online (Sandbox Code Playgroud)
关于第二种,有很多更好的方法来散列字符串.例如,请参阅此处了解一些C示例(可以根据上面的代码段轻松转换为C++).
小智 5
这是我在Stroustrup的书中找到的C(++)哈希函数:
int hash(const char *str)
{
int h = 0;
while (*str)
h = h << 1 ^ *str++;
return h;
}
Run Code Online (Sandbox Code Playgroud)
如果你将它用于哈希表(Stroustrup会这样做),那么你可以改为以模数的形式返回哈希模数.所以与其
return (h > 0 ? h : -h) % N_BUCKETS;
Run Code Online (Sandbox Code Playgroud)
为最后一行.