【问题标题】:When is Rabin Karp more effective than KMP or Boyer-Moore?Rabin Karp 什么时候比 KMP 或 Boyer-Moore 更有效?
【发布时间】:2019-10-18 12:02:30
【问题描述】:

我正在学习字符串搜索算法并了解它们的工作原理,但还没有找到足够好的答案来说明在哪些情况下 Rabin-Karp 算法会比 KMP 或 Boyer-Moore 更有效。我发现它更容易实现并且不需要相同的开销,但除此之外,我不知道。

那么,Rabin-Karp 什么时候比其他方法更好用?

【问题讨论】:

    标签: string-search knuth-morris-pratt rabin-karp boyer-moore


    【解决方案1】:

    这些算法中的每一个都具有一些属性,这些属性可能使它们在不同的情况下成为可取或不可取的。以下是简要介绍:

    太空使用有利于拉宾-卡普

    Rabin-Karp 的一个主要优点是它使用 O(1) 辅助存储空间,如果您要查找的模式字符串非常大,这将非常有用。例如,如果您要在长度为 109 的较长字符串中查找长度为 107 的字符串的所有匹配项,则不必分配 107 用于故障函数或移位表的机器词是一个重大胜利。 Boyer-Moore 和 KMP 都在长度为 n 的模式字符串上使用 Ω(n) 内存,因此 Rabin-Karp 在这里将是一个明显的胜利。

    最坏情况的单场比赛效率有利于 Boyer-Moore 或 KMP

    Rabin-Karp 有两种潜在的最坏情况。首先,如果恶意对手知道 Rabin-Karp 使用的特定素数,那么该对手可能会制作一个输入,使滚动散列在每个时间点与模式字符串的散列相匹配,从而导致算法的性能下降。在长度为 m 的字符串和长度为 n 的模式上降级为 Ω((m - n + 1)n)。如果您将不受信任的字符串作为输入,这可能是一个问题。 Boyer-Moore 和 KMP 都没有这些弱点。

    最坏情况下的多重匹配效率有利于 KMP。

    类似地,如果您想在该模式多次出现的情况下查找模式字符串的所有匹配项,Rabin-Karp 会很慢。例如,如果您要在由字母 a 的 109 个副本组成的文本字符串中查找字母 a 的 105 个副本的字符串Rabin-Karp,那么会有很多点出现模式串,每个点都需要线性扫描。这也可能导致 Ω((m + n - 1)n) 的运行时间。

    许多 Boyer-Moore 实现都受到第二条规则的影响,但在第一种情况下不会有糟糕的运行时。而且 KMP 没有像这样的病态最坏情况。

    最佳案例表现有利于 Boyer-Moore

    Boyer-Moore 算法的一个优点是它不必扫描输入字符串的所有字符。具体来说,坏字符规则可用于在不匹配的情况下跳过输入字符串的大块区域。更具体地说,Boyer-Moore 的最佳运行时间是 O(m / n),这比 Rabin-Karp 或 KMP 所能提供的要快得多。

    多字符串的泛化支持 KMP

    假设您要搜索一组固定的多个文本字符串,而不仅仅是一个。如果您愿意,您可以在字符串上运行多次 Rabin-Karp、KMP 或 Boyer-Moore 以查找所有匹配项。但是,这种方法的运行时间不是很好,因为它与要搜索的字符串的数量呈线性关系。另一方面,KMP 很好地推广到 Aho-Corasick 字符串匹配算法,该算法在 O(m + n + z) 时间内运行,其中 z 是找到的匹配数,n 是模式字符串的组合长度。请注意,这里不依赖于正在搜索的不同模式字符串的数量!

    【讨论】:

    • 关于你最后一个标题“泛化到多个字符串”的另一件事:如果我们正在寻找的模式集中的每个模式都具有相同的长度 m,那么 Rabin Karp 有 O(n + km)复杂性
    【解决方案2】:

    Rabin-Karp 算法在搜索查找多个模式匹配的大文本时效果更好,例如检测抄袭。

    Boyer-Moore 在模式相对较大且字母大小适中且词汇量较大的情况下效果更好。而且它不适用于二进制字符串或非常短的模式。

    同时,KMP 适合在较小的字母表中搜索,例如在生物信息学中或在二进制字符串中搜索。如果字母增加,它也不会跑得很快。

    【讨论】:

    • 如果字母表增加,为什么 KMP 运行不快?我从未见过解释过这个引理。
    • KMP 只访问每个字符一次(线性运行时),Boyer-Moore 可以跳过字符序列(次线性运行时)。字符序列的跳过取决于模式末尾的不匹配,较大的字母更可能发生这种情况。
    【解决方案3】:

    三者的时空复杂性(供参考) (用于查找所有出现的模式)

    m : 模式的长度

    n : 我们在其中搜索模式的字符串的长度

    k : 字母的大小

    拉宾·卡普:

    O(1) 个辅助空间

    使用散列来查找文本中模式字符串的完全匹配。它使用滚动散列快速过滤掉与模式不匹配的文本位置,然后检查剩余位置是否匹配

    博耶摩尔:

    最坏情况下的性能:Θ(m) 预处理 + O(mn) 匹配

    最佳情况性能:Θ(m) 预处理 + Ω(n/m) 匹配

    最坏情况空间复杂度:Θ(k)。

    可用于类似“grep”的搜索。 https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string-search_algorithm#Performance

    克努斯·莫里斯·普拉特:

    最坏情况下的性能:Θ(m) 预处理 + Θ(n) 匹配

    最坏情况空间复杂度:Θ(m)

    有关每种算法的更多详细信息,请在 Wikipedia 中查找。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-02
      • 1970-01-01
      • 2021-10-07
      • 1970-01-01
      • 1970-01-01
      • 2012-04-02
      • 1970-01-01
      • 2010-10-28
      相关资源
      最近更新 更多