Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 为什么要设置哈希表';s长度到质数是一个好的做法吗?_Arrays_Hash_Primes - Fatal编程技术网

Arrays 为什么要设置哈希表';s长度到质数是一个好的做法吗?

Arrays 为什么要设置哈希表';s长度到质数是一个好的做法吗?,arrays,hash,primes,Arrays,Hash,Primes,我正在浏览Eric Lippert的最新博文,当我点击以下段落时: 我们在这里可以更聪明;正如列表在满时调整自身大小一样,bucket集也可以调整自身大小,以确保平均bucket长度保持较低。此外,出于技术原因,将桶集长度设置为素数而不是100通常是一个好主意。我们可以对这个哈希表进行很多改进。但是这个简单的哈希表实现现在就可以了。我想保持简单 看来我遗漏了什么。为什么将它设置为素数是一种好的做法 因为这样可以生成更好的哈希函数并减少可能的冲突数量。下文对此进行了解释: 一个基本要求是 功能应提

我正在浏览Eric Lippert的最新博文,当我点击以下段落时:

我们在这里可以更聪明;正如列表在满时调整自身大小一样,bucket集也可以调整自身大小,以确保平均bucket长度保持较低。此外,出于技术原因,将桶集长度设置为素数而不是100通常是一个好主意。我们可以对这个哈希表进行很多改进。但是这个简单的哈希表实现现在就可以了。我想保持简单


看来我遗漏了什么。为什么将它设置为素数是一种好的做法

因为这样可以生成更好的哈希函数并减少可能的冲突数量。下文对此进行了解释:

一个基本要求是 功能应提供统一的 散列值的分布。A. 非均匀分布增加了 碰撞的次数,以及碰撞的成本 解决它们

分配需要统一 仅适用于中出现的表格大小 应用程序。特别是,如果有 使用动态调整大小和精确调整大小 s的加倍和减半,散列 只有在以下情况下,函数才需要统一 s是二的幂。另一方面 另一方面,一些哈希算法提供 仅当s是素数时,统一散列 号码


假设你的桶集长度是2的幂-这使得mod计算相当快。这还意味着bucket选择仅由哈希代码的顶部
m
位确定。(式中,
m=32-n,其中n是所用2的幂)。这就好像你马上扔掉了有用的哈希代码

或者如2006年的一篇文章所说:

假设您的hashCode函数产生以下hashCode以及其他{x,2x,3x,4x,5x,6x…},那么所有这些都将聚集在m个bucket中,其中m=table_length/GreatestCommonFactor(table_length,x)。(验证/推导这一点很简单)。现在,您可以执行以下操作之一以避免群集:

或者简单地通过使最大公因子(table_length,x)等于1,即通过使table_length与x互质,使m等于table_length。如果x可以是任意一个数,那么确保table_length是一个素数


你可以找到一些人,他们提出了两种截然不同的观点。一方面,为哈希表的大小选择一个素数将减少冲突的机会,即使哈希函数在分配结果方面不是很有效。请注意,如果(在最简单的例子中)决定了2个大小的幂,则只有较低的位会影响bucket,而对于素数,将使用散列结果中的大多数位

另一方面,通过选择更好的散列函数,甚至通过应用一些位操作来重新设置散列函数的结果,并使用2个散列大小的幂来加速计算,您可以获得更多

作为现实生活中的一个例子,Java哈希表最初是通过使用素数(或几乎素数大小)实现的,但从Java 1.4开始,设计更改为使用两个桶的幂,并添加了第二个快速哈希函数应用于初始哈希的结果。一篇有趣的文章评论了这一变化

所以基本上:

  • 质数有助于将输入分散到不同的存储桶中,即使在哈希函数不太好的情况下也是如此

  • 通过对哈希函数的结果进行后处理,并使用2个大小的幂来加速模运算(位掩码)并补偿后处理,可以实现类似的效果


当.Net framework中内置了更好、经过测试且速度更快的实现时,为什么还要编写自己的呢?请在System.Collections下进行检查。@Will我不会写我自己的。。而且Eric只是举了个例子…这能回答你的问题吗+1这是一个很好的答案。。。但是,在给定的范围内,我们不能减少散列的数量……我知道这是在复活一个旧线程,但是你的第一段让我困惑。考虑2的幂为128,在这种情况下散列% 128将与哈希和127相同,这意味着只有最后7位将决定桶选择。还是我的理解错了?