你能从1.25美元的书中期待什么呢?
无论如何,多年来我一直在思考数学的本质,但仍然无法理解。
当桶的数量是质数时,数字的分布是否真的更均匀?
还是这只是一个老程序员传说,因为每个人都接受它?
通常,一个简单的哈希函数通过获取输入的“组成部分”(在字符串的情况下是字符),将它们乘以某个常数的幂,并将它们加在一起形成某种整数类型。因此,例如,字符串的典型哈希(虽然不是特别好的)可能如下:
(first char) + k * (second char) + k^2 * (third char) + ...
来源- http://srinvis.blogspot.com/2006/07/hash-table-lengths-and-prime-numbers.html
总结一下从答案中得出的一些想法。
10
,十六进制中的16
)作为模数,因为 11 % 10 -> 1
,21 % 10 -> 1
,31 % 10 -> 1
,这显示了哈希值分布的清晰模式:具有相同末位数字的值将会碰撞10^2
、10^3
、10^n
)作为模数,因为它也会创建一个模式:具有相同末尾的n
个数字的值将会发生碰撞1
以外的因子的东西,因为它会创建一种模式:因子的倍数将哈希成选定的值9
具有3
作为因子,因此3
、6
、9
、...999213
将始终被哈希为0
、3
、6
12
有因子3
和2
,因此2n
将总是散列到0
、2
、4
、6
、8
、10
,3n
将总是散列到0
、3
、6
和9
3n
,那么我们只得到了所有可能哈希值的1/3
,冲突率很高0
,否则哈希值分布均匀http://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/
这篇文章给出了清晰的解释,还配有图片。
编辑:简单来说,使用质数是因为选择一个质数作为乘数后,将值相乘并全部加起来可以得到最佳的唯一值。例如,对于一个给定的字符串,将每个字母的值乘以质数再将它们相加,可以得到该字符串的哈希值。
更好的问题应该是,为什么恰好是数字31?
*32
是一个简单的位移操作,甚至更好的做法是使用立即地址比例因子(例如,在x86/x64上使用lea eax, eax*8; leax, eax,eax*4
)。因此,*31
是质数乘法的一个很好的选择。几年前这基本上是正确的——现在最新的CPU架构具有近乎瞬时的乘法,但除法始终较慢... - Arnaud Bouchez使用质数是因为您有很好的机会获得一个典型哈希函数的唯一值,该哈希函数使用模P的多项式。假设您将这样的哈希函数用于长度小于或等于N的字符串,并且发生冲突。这意味着两个不同的多项式产生了相同的模P的值。这些多项式的差异又是同一次数N(或更少)的多项式。它最多只有N个根(这里体现了数学的本质,因为这个声明只适用于一个素数域上的多项式 => 素数)。因此,如果N远小于P,则可能不会发生冲突。之后,实验可能会表明37足以避免在链表中出现碰撞,而且对于长度为5-10的字符串的哈希表来说,它也足够小以进行计算。
index[hash(input)%2]
会导致一半的可能哈希值和范围内的值发生冲突。而index[hash(input)%prime]
则只有不到2%的可能哈希值产生冲突。将除数固定为表格大小还可以确保数字不大于表格大小。
index[hash(input)%prime]
导致小于所有可能哈希的2个碰撞,其中 prime > 2_,它仍然没有意义,因为该条件对于任何大于2的数字都成立。 - alelom提供一种替代观点,这里有一个网站:
http://www.codexon.com/posts/hash-functions-the-modulo-prime-myth
该网站认为,您应该使用尽可能多的存储桶,而不是将其舍入为质数。这似乎是一个合理的可能性。直觉上,我肯定能看出更多的存储桶会更好,但我无法做出数学论证。
n%m = n - floor(n/d)
。你所提到的不是质数模数,而似乎是线性探测(field1,field2 ...)与一个名为模数的乘数矛盾地结合。但是,如何确保您的哈希是小于表大小的数字?您需要将其缩小,通常使用取模来完成。 - Wolfgang Brehm这取决于哈希函数的选择。
许多哈希函数将数据中的各个元素与一些因子相乘,模数是机器字长对应的二次幂(只需让计算溢出即可使模数自由)。
你不希望在数据元素的乘法器和哈希表大小之间有任何共同因子,因为这样可能会导致改变数据元素时数据未能分散到整个表中。如果你选择质数作为表的大小,则这种共同因子的可能性非常小。
另一方面,这些因子通常由奇质数组成,因此在哈希表中使用二的幂也是安全的(例如,Eclipse在生成Java hashCode()方法时使用31)。