String Rabin Karp:滚动散列计算将一个大素数添加到先前计算的散列中

String Rabin Karp:滚动散列计算将一个大素数添加到先前计算的散列中,string,montecarlo,rolling-computation,rabin-karp,String,Montecarlo,Rolling Computation,Rabin Karp,我想我在概念上理解了使用滚动哈希的RabinKarp模式匹配算法。在查看示例实现时,我发现在先前计算的滚动哈希中添加了一个大素数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 h

我想我在概念上理解了使用滚动哈希的RabinKarp模式匹配算法。在查看示例实现时,我发现在先前计算的滚动哈希中添加了一个大素数
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;
        }
for(int i=m;i
我不知道为什么需要这样做。我能得到一些帮助吗

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


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

术语
+q
用于避免处理负数

我们希望
txtHash
始终位于区间
[0;q[
,如果没有这个
+q
,它也可能位于
]-q;0[


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

+q
,这对我来说也是一个错误,因为它的价值。@500 InternalServerError谢谢!你能不能解释一下,当包含
+q
时,为什么我们会得到正确的结果?如果我在没有+q的情况下运行该算法,它还会工作吗?我问的原因是我刚刚了解到-3%7=4%7=4,所以只要有q的模块,负的中间哈希就不会有任何副作用。
%
在Java中不是这样的模运算符,但余数。因此,在Java中,
-3%7=-3
4%7=4
,当然还有
-3!=4
。请参见例如,感谢您为我简化了这一点。我想我现在理解了总体思路,但在理解确切的数学方面仍然有点困难。