【问题标题】:When would you use KMP over BOYER-MOORE你什么时候会在 BOYER-MOORE 上使用 KMP
【发布时间】:2013-04-18 14:05:08
【问题描述】:

我目前正在学习模式匹配算法,并且遇到过这两种算法。我有以下一般想法:

KMP

  • 从左到右比较文本
  • 使用故障数组智能切换
  • 计算失败数组需要 O(m),其中 m 是模式的长度
  • 占用 O(m),空间
  • 需要 O(n),时间来搜索一个字符串

BM

  • 比较最后一个字符的模式
  • 使用不好的字符跳转和好的后缀跳转
  • 计算表需要 O(m + 字母大小)
  • 占用 O(m + 字母大小),空格
  • 需要 O(n),但通常更好搜索

我遇到了以下引发此问题的问题(对或错):

如果我们想要,Knuth-Morris-Pratt (KMP) 算法是一个不错的选择 在许多不同的文本中重复搜索相同的模式。

所以我相信答案是正确的,因为假设每次您在不同的文本上运行算法时,预处理只是 O(n),而对于 BM,它是 O(n + 字母大小)。但是,我不确定我是否做出了正确的假设,即每次重新运行算法时都会重新计算一个新表。因为说文本总是落在英文字母表中。我只需要计算一次表并重用该表。因此,归根结底,这个问题的答案是否取决于算法都在包含在同一个字母表中的文本上运行这一事实,还是有其他可能影响它的因素?

【问题讨论】:

  • 这里有很多信息:stackoverflow.com/q/12656160/56778,以及其他 SO 帖子。在 Google 上搜索 [kmp vs boyer-moore]。
  • @JimMischel 我已经看过那篇文章,但它并没有直接回答我问题的主要部分。我已经尝试用谷歌搜索了
  • 这正是我正在寻找的。任何帮助将不胜感激。

标签: algorithm pattern-matching boyer-moore knuth-morris-pratt


【解决方案1】:

理论上,两种算法都会有“相似”的性能; KMP 将在搜索阶段进行大约 2n 次比较,而 Boyer-Moore 将在搜索阶段进行大约 3n 次比较在最坏的情况下。在这两种情况下,您都不需要在获得新文本时重复预处理。

但真正的答案是你不应该在实践中使用任何一种。

这两种算法所需的线性辅助存储会导致相当多的...由于所有额外的内存访问,现代架构的性能会更加粗糙。

然而,Boyer-Moore 和 KMP 背后的想法是大多数快速字符串匹配算法的基础。我所知道的每一个实际有效的字符串匹配算法都使用了类似 KMP 的“故障函数”的想法;事实证明,您可以动态计算模式的次优“故障函数”,该模式仍然为您提供线性时间匹配,同时只需要恒定的额外空间。在将固定模式与随机噪声匹配的“平均情况”中,Boyer-Moore 比线性更快,这在许多实际情况下都得到证实。

【讨论】:

  • 值得注意的是,C++ 的 Boost 有两个匹配器,而且它们工作得很好。
  • @Mehrdad:不过,恒定空间 KMP 变体击败了直 KMP。 Boyer-Moore 能否胜出通常取决于您的意见。
  • 有趣的答案,但如果您能说出实际应该使用哪种算法(如果不是 KMP 或 BM),那就太好了。
  • @0sh:“双向字符串匹配”,由于 Crochemore 和 Perrin,在理论上和实践上都是有效的。它是对“使用最大后缀的字符串匹配”的改进,在实践中也相当快;我不确定该算法归于谁。
猜你喜欢
  • 2019-10-18
  • 2021-10-07
  • 2011-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-13
  • 2014-06-29
  • 1970-01-01
相关资源
最近更新 更多