【问题标题】:Rabin-Karp: rolling hash computation adds a large prime number to previously computed hashRabin-Karp:滚动散列计算将一个大素数添加到先前计算的散列中
【发布时间】:2019-10-09 05:13:17
【问题描述】:

我想我在概念上理解使用滚动哈希的 RabinKarp 模式匹配算法。在通过示例实现here 时,我发现一个大素数q 被添加到先前计算的滚动哈希中。

for (int i = m; i < n; i++) {
            // Remove leading digit, add trailing digit, check for match. 
            txtHash = (txtHash + q - RM*txt.charAt(i-m) % q) % q; //Why +q here?
            txtHash = (txtHash*R + txt.charAt(i)) % q; 

            // match
            int offset = i - m + 1;
            if ((patHash == txtHash) && check(txt, offset))
                return offset;
        }

我不确定为什么需要这样做。我能得到一些帮助吗?

在我的有限测试中,无论是否包含q 术语,我都得到相同的结果。

这是否与正在实施的算法版本(蒙特卡洛/拉斯维加斯)有关?

【问题讨论】:

  • + q 在我看来也是一个错误,因为它值得。
  • @500-InternalServerError 谢谢!您能否解释一下为什么在包含+q 时我们会得到正确的结果?

标签: string montecarlo rolling-computation rabin-karp


【解决方案1】:

+q 是为了避免处理负数。

我们希望 txtHash 始终位于区间 [0;q[ 中,没有此 +q 它也可能位于 ]-q;0[ 中。

这可能会导致模式丢失。例如,如果 patHash = 0xdead 但您计算 txtHash = -q+0xdead。这两个值在数学上是相等的 mod q 但与采用 Java 的 % q 不同。

【讨论】:

  • 如果我在没有 +q 的情况下运行算法,它是否仍然有效。我问的原因是我刚刚了解到-3%7 = 4%7 = 4,所以只要有 q 的模块,负中间哈希就不会有任何副作用。
  • % 在 Java 中不是模运算符,而是余数 docs.oracle.com/javase/specs/jls/se8/html/… 。因此在 Java 中,-3%7=-34%7=4,当然还有-3 != 4。参见例如programming.guide/java/…
  • 感谢您为我解惑。我想我现在理解了整体的想法,但我在理解确切的数学方面仍然有点困难。
猜你喜欢
  • 2022-01-18
  • 2018-03-08
  • 2012-02-20
  • 2017-07-18
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多