Rabin-Karp 算法:为啥 h=(h*d)%q

Posted

技术标签:

【中文标题】Rabin-Karp 算法:为啥 h=(h*d)%q【英文标题】:Rabin-Karp algorithm: Why is h=(h*d)%qRabin-Karp 算法:为什么 h=(h*d)%q 【发布时间】:2021-11-18 08:30:44 【问题描述】:

我理解 Rabin-Karp 算法中的以下内容

h=d^m-1 但我不明白我们为什么要写

for(i=0;i<M-1;i++)
    h=(h*d)%q

在代码中

【问题讨论】:

我怀疑这个问题中是否有足够的数据可供任何人提供有用的答案。你能分享你引用的实现吗? (从开放编码的合并链看起来是一个不完整的 sn-p。) 这是来自算法的Java编码 无论来自什么,你都应该参考你的来源,让别人理解你的观点并给予提示 【参考方案1】:

基本上,这些行正在为您的哈希映射初始化默认值,稍后您将对其进行更改,并且它还可以用作哈希函数,当您将插入值时,为了更深入,请阅读下面的段落,也可以投票并关注我的简历 。 当你试图理解 hashmaps 的概念时,每个人都会通过串联一些块来教你。后来,这些块被初始化了一些键值,但在您插入键值之前,这些块未初始化。所以可能有一些块没有被赋予任何关键值。它们将包含垃圾值,以及如何遍历它们,因为当您需要搜索某些内容时,您需要遍历,因此该函数正在为所有块初始化默认值。现在,如果您尝试在没有这些行的情况下运行您的代码,您的代码将只检查第一次。据我所知,这些代码行来自 geeksforgeeks rabinkarp 算法,请尝试在没有这些行的情况下运行该代码,您将只检查第一个值而不会得到所需的答案

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案2】:

准确地说,循环不是在计算 ℎ=??−1,而是 ℎ=(??− 1) 模组?。这是一个重要的细节,因为这意味着无论?或?的值是多少,结果都不会超过?。

另外,您提供的代码块需要在前面加上h=1 才有意义。

通过循环,我们可以避免较大的中间结果,这可能会超出所使用的整数类型支持的范围。通常字符串字母 (?) 的大小设置为 256。现在如果要搜索的模式的长度 (?) 像 20,那么?? = 25620 = 2160,一个不适合典型 32 位或 64 位整数存储的数字。所以像这样计算??−1有可能导致数值溢出。

这就是使用循环的原因。在每次迭代中,都会应用模运算符,它使用正常的 ? 和 ? 值消除了溢出的风险。在每次迭代时应用模运算符也是correct。

【讨论】:

以上是关于Rabin-Karp 算法:为啥 h=(h*d)%q的主要内容,如果未能解决你的问题,请参考以下文章

Rabin-Karp ACM训练

Rabin-Karp 滚动哈希

为啥在内核启动之前开始数据迁移(D 到 H)?

Rabin-Karp 字符串搜索算法

PHP 中的 Rabin-Karp 算法

C# 中的 Rabin-Karp 算法 [关闭]