我一直没能理解哈希函数的设计。我正在经历一个例子。正如您在函数注释中所看到的,为什么要选择31作为要乘的数字。你是如何决定的?这是随机的还是意味着什么?
unsigned int hash(hash_table_t *hashtable, char *str)
{
unsigned int hashval;
/* we start our hash out at 0 */
hashval = 0;
/* for each character, we multiply the old hash by 31 and add the current
* character. Remember that shifting a number left is equivalent to
* multiplying it by 2 raised to the number of places shifted. So we
* are in effect multiplying hashval by 32 and then subtracting hashval.
* Why do we do this? Because shifting and subtraction are much more
* efficient operations than multiplication.
*/
for(; *str != '\0'; str++) hashval = *str + (hashval << 5) - hashval;
/* we then return the hash value mod the hashtable size so that it will
* fit into the necessary range
*/
return hashval % hashtable->size;
}
答案 0 :(得分:3)
有问题的哈希被称为伯恩斯坦哈希,托雷克哈希,或简称为“时代33”哈希。它非常受欢迎,因为它的简单性,速度和使用英语字符串数据的良好分布。
你的评论注意它实际上乘以31,这对你来说似乎是随意的,实际上 有点武断。 Apache Portable Runtime has a comment in their hash algorithm source指出许多可能的常量运作良好(33是最常见的)。它们都是奇数并且接近2的幂,这意味着它们很好地转换为移位和加法或减法。
其他一些有助于理解哈希的资源:
答案 1 :(得分:1)
这是一个有65k视图的哈希函数讲座。在youtube上:http://www.youtube.com/watch?v=KW0UvOW0XIo
这并不是您要求的,但是您的问题表明您对哈希的了解有限。最好阅读教程或检查演示文稿。