很久以前,我花1.25美元在便宜货桌上买了一本数据结构的书。在这篇文章中,哈希函数的解释说,由于“数学的本质”,它最终应该被一个质数mod。
你对一本1.25美元的书有什么期待?
不管怎么说,我花了很多年思考数学的本质,但还是没弄明白。
当有质数个桶时,数字的分布真的更均匀吗?
或者这是一个老程序员的故事,每个人都接受,因为其他人都接受?
很久以前,我花1.25美元在便宜货桌上买了一本数据结构的书。在这篇文章中,哈希函数的解释说,由于“数学的本质”,它最终应该被一个质数mod。
你对一本1.25美元的书有什么期待?
不管怎么说,我花了很多年思考数学的本质,但还是没弄明白。
当有质数个桶时,数字的分布真的更均匀吗?
或者这是一个老程序员的故事,每个人都接受,因为其他人都接受?
当前回答
只是把从答案中得到的一些想法写下来。
Hashing uses modulus so any value can fit into a given range We want to randomize collisions Randomize collision meaning there are no patterns as how collisions would happen, or, changing a small part in input would result a completely different hash value To randomize collision, avoid using the base (10 in decimal, 16 in hex) as modulus, because 11 % 10 -> 1, 21 % 10 -> 1, 31 % 10 -> 1, it shows a clear pattern of hash value distribution: value with same last digits will collide Avoid using powers of base (10^2, 10^3, 10^n) as modulus because it also creates a pattern: value with same last n digits matters will collide Actually, avoid using any thing that has factors other than itself and 1, because it creates a pattern: multiples of a factor will be hashed into selected values For example, 9 has 3 as factor, thus 3, 6, 9, ...999213 will always be hashed into 0, 3, 6 12 has 3 and 2 as factor, thus 2n will always be hashed into 0, 2, 4, 6, 8, 10, and 3n will always be hashed into 0, 3, 6, 9 This will be a problem if input is not evenly distributed, e.g. if many values are of 3n, then we only get 1/3 of all possible hash values and collision is high So by using a prime as a modulus, the only pattern is that multiple of the modulus will always hash into 0, otherwise hash values distributions are evenly spread
其他回答
博士tl;
Index [hash(input)%2]将导致所有可能哈希值的一半和一段值发生冲突。Index [hash(input)%prime]导致所有可能哈希值中的<2的碰撞。将除数固定为表的大小还可以确保数字不能大于表。
抄袭我的其他答案https://stackoverflow.com/a/43126969/917428。有关更多细节和示例,请参阅它。
我相信这和电脑在2进制下工作有关。想想以10为基数的情况:
8%10 = 8 18%10 = 8 87865378%10 = 8
不管这个数是多少只要它以8结尾,它对10的模就是8。
选择一个足够大的、非2的幂的数字将确保哈希函数实际上是所有输入位的函数,而不是它们的子集。
http://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/
解释得很清楚,还有图片。
编辑:作为一个总结,使用质数是因为当数值乘以所选质数并将它们全部相加时,获得唯一值的可能性最大。例如,给定一个字符串,将每个字母的值与质数相乘,然后将它们全部相加,就会得到它的哈希值。
一个更好的问题是,为什么是数字31?
Primes are unique numbers. They are unique in that, the product of a prime with any other number has the best chance of being unique (not as unique as the prime itself of-course) due to the fact that a prime is used to compose it. This property is used in hashing functions. Given a string “Samuel”, you can generate a unique hash by multiply each of the constituent digits or letters with a prime number and adding them up. This is why primes are used. However using primes is an old technique. The key here to understand that as long as you can generate a sufficiently unique key you can move to other hashing techniques too. Go here for more on this topic about http://www.azillionmonkeys.com/qed/hash.html
http://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/
我读过一个流行的wordpress网站,上面有一些流行的答案。根据我的理解,我想分享一个简单的观察。
你可以在这篇文章中找到所有的细节,但假设以下是正确的:
使用质数给我们提供了一个唯一值的“最佳机会”
一个通用的hashmap实现需要有两个东西是唯一的。
键的唯一哈希码 用于存储实际值的唯一索引
我们如何得到唯一索引?通过使内部容器的初始大小也是质数。基本上,质数的存在是因为它具有产生唯一数字的独特特性,我们最终用它来标识对象并在内部容器中查找索引。
例子:
Key = " Key "
Value = " Value " uniqueId = "k" * 31 ^ 2 + "e" * 31 ^ 1 ' + “y”
映射到唯一id
现在我们想要一个独特的位置来存放我们的价值,所以我们
uniqueId % internalContainerSize == uniqueLocationForValue,假设internalContainerSize也是质数。
我知道这是简化的,但我希望你能理解我的大意。