【问题标题】:Have you ever used KMP or BM algorithms?你用过 KMP 或 BM 算法吗?
【发布时间】:2011-04-09 05:24:29
【问题描述】:

我知道 KMP (Knuth–Morris–Pratt) 和 BM (Boyers-Moore) 算法都是很好的字符串搜索操作算法。 我也知道BM比KMP快3-5倍。

在您为行业软件编程的经验中,您曾经使用过 BM 或 KMP 算法吗? 算法在这里真的很重要吗?

【问题讨论】:

  • 我知道 KMP 代表什么,但不知道 BM。你介意写下它们各自代表什么,以防其他人不知道吗?
  • @Mehrdad:BM 可能是 Boyer-Moore。
  • 是的。 BM是博耶摩尔。如果你在谷歌上搜索“BM 算法”。你可以找到它。
  • 我不知道你为什么会关心,但我在真实软件中使用了周日的 Boyer-Moore-Horspool 变体。

标签: algorithm


【解决方案1】:

如果您查看例如 Java 的 String.indexOf 函数,它们似乎使用蛮力方法进行字符串匹配。 您可能想知道为什么会这样。

原因是在这些算法中执行了一些查询预处理,这可能代价高昂(尤其是对于 BM,如果您同时使用两个数组)。因此,在 KMP 和 BM 可以击败蛮力方法之前,您搜索的字符串必须很大。

在使用不同的算法和处理大字符串时总是需要权衡取舍,您可以考虑对文本进行索引而不是查询(例如后缀树)。当您每次处理新文本时,这甚至可能很有用。

在我看来,这些算法相当学术,只在特殊情况下有用。

【讨论】:

  • 有趣的是,gcc strstr() 实现(相当于 String.indexOf())使用了一种非常酷的算法,它只需要线性时间,并且与 BM 和 KMP 不同,恒定空间。这基本上消除了在库函数中使用朴素 O(n^2) 方法的任何理由,因为它更快的唯一情况是在两种算法已经非常(即足够)快的极短字符串上。 (从 MAK 的回答中得到。)
  • 其实String的real indexOf方法通常不是你在JDK源码中看到的,而是JDK插入的内在版本,至少在 Sun 的 Java 6 和 7 热点中。事实上,该版本确实使用了 BM 的简化变体。它仅适用于检查的字符根本不在字符串中的情况,在这种情况下,它通常(见注)跳过 N 个字符,其中 N 是搜索字符串的长度。注意:通常的出现是因为算法使用了一个32项的哈希表来判断一个字符是否出现在字符串中,所以有可能发生冲突。
  • 很有趣,因为在iptables 中,您唯一的选择是 BM 和 KMP...
【解决方案2】:

glibc 的strstr 函数是线性的。它使用Two-Way Algorithm,我认为它是Boyer-Moore 的变体。所以,我猜这使得任何在 gcc 中使用strstr 的人实际上是在使用现实世界中的快速字符串搜索算法。

至于快速算法是否重要的​​问题,恕我直言,只有当数据量足够大时才重要。我们所做的很多显式字符串操作都是针对非常小的字符串(比如少于 500 个字符)。这并不是说我们不做繁重的字符串操作(例如,在数据库上进行全文搜索),但在那种情况下,我们通常让数据库或库为我们做繁重的工作。数据库或库使用快速字符串搜索算法 - 所以我不会说它们无关紧要,只是它的使用对我们来说是不直接可见的。

【讨论】:

  • 哇!线性时间和恒定空间,它符合所有条件!想知道为什么我以前没有听说过这个算法。不得不说我无法理解www-igm.univ-mlv.fr/~lecroq/string/node26.html#SECTION00260 的解释,所以我下载了 Crochemore & Perrin 1991 年的论文,但发现它有 25 页不祥的页面——超过了我的“随意阅读”阈值。 :/ 一天...
  • @j_random_hacker:我也很难跟上。我想正是因为这个原因,它不像 KMP 或 Rabin Karp 那样受欢迎。
【解决方案3】:

我在硬件上实现了一次 KMP。如果硬件是 FPGA,您可以使用可重构性来拥有自修改电路。该电路获取搜索字符串。比在硬件中进行必要的预换向并将自身重新配置为实际制作 KMP 的逻辑。但这里也有必要爬取大量数据以加快速度,但在某些情况下确实如此(例如 DNA 匹配)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-25
    相关资源
    最近更新 更多