【问题标题】:Confusion Regarding Rolling Hash in Rabin-Karp Algorithm Java关于 Rabin-Karp 算法 Java 中的滚动哈希的困惑
【发布时间】:2016-09-06 06:53:04
【问题描述】:

我试图在这里理解 Rabin-Karp 算法:http://algs4.cs.princeton.edu/53substring/RabinKarp.java.html

我浏览了各种文章,现在我知道多项式哈希的一般形式是 C1*A^k-1+C2*A^k-2+C3*A^k-3。看了代码,我明白了他们是如何在字符串中加减数字的。

txtHash = (txtHash + Q - RM*txt.charAt(i-M) % Q) % Q; txtHash = (txtHash*R + txt.charAt(i)) % Q;

这里的程序是减去前导数字,乘以整个哈希,然后添加新数字。但是,当我查看计算哈希的函数时,它并没有遵循多项式哈希的一般形式。它看起来像这样:

 private long hash(String key, int M) { 
    long h = 0; 
    for (int j = 0; j < M; j++) 
        h = (R * h + key.charAt(j)) % Q; 
    return h; 
} 

在这个函数中,他们将哈希和基数相乘,然后加上 key.charAt()。我认为该函数会将 key.charAt() 与从 R^k-1 开始的基数相乘。然后随着 for 循环的继续,基数将除以 R 以提供多项式中的递减幂。有人可以解释一下这个函数是如何工作的,以及它是如何以我上面提到的形式生成散列的吗?谢谢!

【问题讨论】:

    标签: java hash rabin-karp


    【解决方案1】:

    假设哈希函数需要传输 3 位数字。 它看起来像:

    {digits[0]*R^2+digits[1]*R^1+digits[2]}%Q  
    = {(digit[0]*R^1+digits[1])*R+digits[2]}%Q  
    

    这将使哈希函数更容易计算。

    然后应用到Rabin-Karp算法,
    你可以看到

    RM = R^2 %Q;(M=2) 
    

    当您想移动下一位进行验证时,
    您需要删除最左边的数字并添加下一个数字。

    txtHash = {[txtHash - R^2*most_left_digit(equal charAt(i-M))]*R+next_digit(equal charAt(i))}%Q  
    

    一样
    txtHash = (txtHash + Q - RM*txt.charAt(i-M) % Q) % Q; 
    txtHash = (txtHash*R + txt.charAt(i)) % Q;
    

    Mod Q 每一步都防止溢出。

    【讨论】:

      猜你喜欢
      • 2023-03-09
      • 1970-01-01
      • 2013-12-23
      • 2017-07-27
      • 2012-01-18
      • 1970-01-01
      • 2018-11-22
      • 2021-05-26
      • 2016-08-17
      相关资源
      最近更新 更多