所以在维基百科上的hash maps article中有这张漂亮的图片:
到目前为止一切都很清楚,除了中间的哈希函数。
1
的{{1}},John Smith
的{{1}}等?答案 0 :(得分:4)
这是hashmaps / dictionaries等关键问题之一。你必须选择一个好的哈希函数。一个非常糟糕但快速的哈希函数可能是密钥的长度。你会立即看到,你会得到很多碰撞(不同的密钥,但是相同的哈希)。另一个错误的哈希函数可能是键的第一个字符的ASCII值。很多碰撞。
所以你需要一个比这两个更好的功能。例如,您可以添加(xor)关键字符的所有ASCII值并混合长度。实际上,您通常依赖于要散列的对象的值(字段)(相同的值给出相同的散列=>值类型)。例如,对于参考类型,您可以混合使用内存位置。
在你的例子中,它只是简化了很多。没有真正的哈希函数会将这些键映射到连续数字。
也许您想阅读我的previous answers to hashmaps
之一答案 1 :(得分:1)
简单的哈希函数可能如下:
$hash = $string[0] % HASH_TABLE_SIZE;
此函数将返回介于0和HASH_TABLE_SIZE - 1之间的数字,具体取决于字符串的第一个字母。此数字可用于转到哈希表中的正确位置。
真正的哈希函数将考虑字符串中的所有字母,并且它将被设计为使得桶之间存在均匀的分布。
答案 2 :(得分:0)
散列函数最常用(但不一定总是)输出所需范围内的整数(通常是散列函数的参数)。该整数可用作索引。请注意,当给出不同的哈希数据时,无法保证哈希函数 始终产生唯一的结果。这称为哈希冲突,哈希算法必须始终以某种方式处理它。
至于您的具体问题,字符串如何成为数字。任何字符串都由字符(J,o,h,n ...)组成,字符可以解释为数字(在计算机中)。 ASCII和UTF标准将某些值绑定到某些字符,因此结果是确定性的,并且在所有计算机上始终相同。因此,哈希函数对这些字符进行操作,将它们作为数字处理,并提供另一个数字(输出)。例如,您可以简单地对所有值求和,并使用模运算来限制结果值。
这将是一个非常糟糕的散列函数,因为例如“ab”和“ba”会得到相同的结果。散列函数的设计很困难,所以应该使用一些现成的算法,除非情况决定了其他一些解决方案。
答案 3 :(得分:0)
关于MSDN上哈希函数(以及colision检测/解析)的一篇非常好的文章:
Part 2: The Queue, Stack, and Hashtable
您可以跳到标题使用哈希函数压缩序数索引
有一些特定于.NET的部分(当他们谈论.NET默认使用哪种Hash算法时),但在大多数情况下它与语言无关。
答案 4 :(得分:-1)
散列函数需要的是它在给定相同键的情况下返回相同的整数。从技术上讲,总是返回'1'的哈希函数不正确。