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 滚动哈希的主要内容,如果未能解决你的问题,请参考以下文章