Rabin-Karp 滚动哈希

Posted

技术标签:

【中文标题】Rabin-Karp 滚动哈希【英文标题】:Rabin-Karp rolling hash 【发布时间】:2013-10-11 22:15:47 【问题描述】:

在 Coursera 的一个视频中, (http://en.wikipedia.org/wiki/Rolling_hash) 显示为:

public static long getHash(String S)

    long H = 0;

    for (int i = 0; i < S.length(); i++)
        H = (H * 10 + S.charAt(i)) % 997;

    return H;

我认为这是错误的。我认为应该是:

public static long getHash(String S)

    long H = 0;

    for (int i = 0; i < S.length(); i++)
        H = (S.charAt(i) * (int)Math.pow(10, (S.length() - i - 1)) + H) % 997;

    return H;

哪个是正确的,为什么?

【问题讨论】:

【参考方案1】:

你的不可能是对的,因为

(int)Math.pow(10, (S.length() - i - 1))

对于长度超过 11 个字符的任何字符串,对于第一个长度为 11 或长度为 12 个字符的结果为 Integer.MAX_VALUE。例如,对于一个 20 个字符的字符串,当 i == 0 在你的循环中时,这是表达式是

(int)Math.pow(10, (20-0-1))

1019 不适合 int,因此转换结果为 2147483647

【讨论】:

为什么不呢?在每次迭代中,H 的值始终在0 - 996 范围内。你是对的,它看起来不像***的描述,但唯一的区别是它以相反的顺序处理字符。 a^0 应用于最左边的字符,而不是最右边。

以上是关于Rabin-Karp 滚动哈希的主要内容,如果未能解决你的问题,请参考以下文章

Rabin-Karp 滚动哈希

在 rabin-karp 滚动哈希中选择基数和模素数

Rabin-Karp算法代码中的负哈希值

字符串哈希之Rabin-Karp,poj1200

[187].重复的 DNA 序列

[187].重复的 DNA 序列