请解释此代码以计算字符串的哈希码

时间:2011-03-22 07:57:41

标签: algorithm string hash hashcode

我读了一本算法书,其中说明给定字符串的键计算如下

 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

2 个答案:

答案 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并且是正确的,您应该可以从上面的维基百科页面了解它。