【发布时间】:2011-03-07 20:24:19
【问题描述】:
我正在研究基于散列的排序,我发现在散列函数中使用素数被认为是一个好主意,因为将键的每个字符乘以素数并将结果相加会产生一个唯一值(因为素数是唯一的),像 31 这样的素数会产生更好的键分布。
key(s)=s[0]*31(len–1)+s[1]*31(len–2)+ ... +s[len–1]
示例代码:
public int hashCode( )
{
int h = hash;
if (h == 0)
{
for (int i = 0; i < chars.length; i++)
{
h = MULT*h + chars[i];
}
hash = h;
}
return h;
}
我想了解为什么在下面的解释中使用偶数乘以每个字符是一个坏主意(在另一个论坛上找到;这听起来像是一个很好的解释,但我没能理解它)。如果以下推理不成立,我将不胜感激。
假设 MULT 为 26,并考虑 散列一百个字符的字符串。 弦的影响有多大 第一个角色在决赛中 “h”的值?第一个字符的值 将乘以 MULT 99 次,所以如果算术完成 在无限精度下,该值将 由一些混乱的位组成 后跟 99 个低位零位—— 每次乘以 MULT 你 引入另一个低阶零, 正确的?计算机是有限的 算术只是砍掉所有 多余的高阶位,所以第一个 角色对“h”的实际贡献 是……正好为零! “h”值 仅取决于最右边的 32 字符串字符(假设为 32 位 int),即使这样,事情也不是 精彩:最后 32 个中的第一个 字节只影响最左边的位 'h' 并且对 剩下 31 个。显然,一个偶数 MULT 是个坏主意。
【问题讨论】:
-
你应该使用
unsigned int,C 中的整数溢出是未定义的行为(任何事情都可能发生)。