我读了一本算法书,其中说明给定字符串的键计算如下
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
使用 int 算术,其中s [i]是字符串的第i个字符,n是字符串的长度,^表示取幂。 (空字符串的哈希值为零。)
或代码:
int h = 0;
for (int i = 0; i < n; i++) {
h = 31*h + s.charAt(i);
}
我的问题是,似乎代码实现并不等同于上面所述的计算方法。例如,给定字符串“ha”(分别为ascii代码104和97)
s [0] * 31 ^(2-1)+ s [1] * 31 ^ 0 = 104 * 31 + 97
从代码执行开始,结果是104 + 31 * 104 + 97
绝对两者不相等,那么如何解释呢?参考链接:http://www.informatics.sussex.ac.uk/courses/dats/notes/html/node114.html
答案 0 :(得分:6)
我认为你误读了代码。
第一次迭代后,h为104。
所以第二次迭代说:
h = 31 * 104 + 97;
......这正是你所期待的。
看起来你误读了这一行:
h = 31 * h + s.charAt(i);
这样:
h += 31 * h + s.charAt(i);
在给出的代码中,我们没有向h
添加新值,我们正在使用简单的赋值。
如果您实际编写了代码并看到了错误的值,请检查您是否有“+ =”而不是“=”。
答案 1 :(得分:4)
你可以做到
int p = 1, h = 0;
for (int i = 0; i < n; i++)
{
p *= 31;
h += s.charAt(n - i - 1) * p;
}
使代码清晰,效率与您的相同。
您的代码使用Horner's scheme并且是正确的,您应该可以从上面的维基百科页面了解它。