Algorithm 散列函数的输出是否需要限制在小于桶数的范围内?

Algorithm 散列函数的输出是否需要限制在小于桶数的范围内?,algorithm,hashtable,hash,Algorithm,Hashtable,Hash,我读到了这个人“在一家知名搜索公司”的采访 他被问到一个问题,这个问题导致他实现了一个哈希表。他说: HASH = INITIAL_VALUE; FOR EACH ( CHAR IN WORD ) { HASH *= MAGIC_NUMBER HASH ^= CHAR HASH %= BOUNDS } RETURN HASH 我解释过哈希表数组 长度应为素数,且边界 数字小于表格长度, 但互质的表长 为什么边界数应该小于桶数?对于表长度来说,互质是做什么的?难道这不应该是无限的互质吗?我敢说

我读到了这个人“在一家知名搜索公司”的采访

他被问到一个问题,这个问题导致他实现了一个哈希表。他说:

HASH = INITIAL_VALUE;
FOR EACH ( CHAR IN WORD ) {
HASH *= MAGIC_NUMBER
HASH ^= CHAR
HASH %= BOUNDS
}
RETURN HASH
我解释过哈希表数组 长度应为素数,且边界 数字小于表格长度, 但互质的表长


为什么边界数应该小于桶数?对于表长度来说,互质是做什么的?难道这不应该是无限的互质吗?

我敢说他完全错了。边界应该是存储桶的数量,否则最后几个存储桶将未被充分利用

此外,输出与桶数的界限应该在哈希函数之外。这是该特定哈希表的实现细节。你可能有一张很大的桌子,上面有很多桶,而另一张桌子上有几个桶。两者应共享相同的字符串->哈希函数

此外,如果你阅读了链接到的页面,它会非常有趣。我会将他的哈希表实现为大约10000个bucket——对于那些没有读过它的人来说,这篇文章建议使用4000000000bucket来存储1000000个左右可能的单词。对于冲突,每个bucket都有一个字结构向量,每个字结构包含一个计数、一个纯文本字符串和一个散列(bucket中唯一)。由于您的工作集要小得多,因此这将使用更少的内存,并与现代缓存一起工作得更好


为了进一步减少内存使用,您可以在输入阶段尝试从哈希中剔除看起来低于当前计数前100000的单词

我曾经在一家著名的猎头公司面试过一份工作。我得到了完全相同的问题。我试图用哈希表来解决这个问题


我从那次采访中学到的一件事是,在一家著名的搜索公司,你不会提出散列作为解决方案。你可以使用任何你喜欢的树状结构,但你总是使用有序结构,而不是哈希表。

一个简单的显式后缀树只会使用最坏情况下的500k内存(具有中等效率的实现、4字节字符编码和重叠最小的相对较长的英语单词)来做同样的事情


我认为这篇文章中的那个家伙比自己聪明。

谢谢汤姆的意见。我觉得他错了,但我不得不让StackOverflow确认自己不是缺乏知识的人。“界限应该是桶的数量,否则最后几个桶将被未充分利用”,你认为当哈希表需要调整大小时,这可能是一种特殊的技巧吗?我完全同意%BOUNDS完全不合适。给定输入的散列应该独立于该散列的用途。您可以将其用作表中的键,可以将其绑在蝴蝶结中,也可以将其管道连接到\dev\null。散列函数应该是非常无知的。@未知-不,这是一个限制。散列函数为地图的大小设置了一个上限。此外,如果映射不是散列边界的倍数,则映射的第一部分(映射边界%hash边界)将被过度使用。哈希函数输出的范围越宽,在一般情况下效果越好。在该范围内,散列输出的均匀分布更为重要。然而,我不是这方面的专家。