【问题标题】:Why is naive string search algorithm faster?为什么朴素的字符串搜索算法更快?
【发布时间】:2013-11-29 17:34:37
【问题描述】:

我正在测试来自此站点的字符串搜索算法:EXACT STRING MATCHING ALGORITHMS. Christian Charras, Thierry Lecroq。测试文本是 1 GB 大小的随机 DNA 碱基序列 (ACGT)。测试模式是随机大小(最大 1kB)的随机序列列表。测试系统是 AMD Phenom II x4 955,3.2 GHz,4 GB RAM 和 Windows 7 64 位。用 C 编写的代码并使用带有 -O3 标志的 MinGW 编译。

朴素搜索算法需要 4 秒的短模式到 8 秒的 1kB 模式。确定性有限状态机对于短模式需要 2 秒,对于 1kB 模式需要 4 秒。 Boyer-Moore 算法对于非常短的模式需要 4 秒,对于短模式大约需要 1/2 秒,对于 1kB 模式需要 2 秒。其余算法性能比朴素搜索算法最差。

朴素搜索算法如何比大多数其他算法搜索算法更快?

使用转换表(总是 O(n) 执行时间)实现的确定性有限状态机如何比 Boyer-Moore 算法慢 2 到 8 倍?是的,BM 最好的情况是 O(n/m),但他的平均情况是 O(n),最坏的情况是 O(nm)。

【问题讨论】:

    标签: string algorithm search


    【解决方案1】:

    没有最适合所有情况的完美字符串匹配算法。

    Boyer-Moore(以及 Horspool、Sunday 等)通过创建跳转表来工作('当字符 匹配时,我可以将搜索指针移动多远?字符串中不同的字母, 积极影响越好。你可以想象,一个只有 4 个不同字母的字符串会创建一个跳转表,每个不匹配最多有 3 个移位。而搜索区分大小写的英文单词可能会导致一个带有 (AZ + az + 标点符号)每个错配最多约 55 个班次。

    另一方面,对准备(即计算跳转表)和循环本身都有负面影响。所以这些算法在短字符串(准备会产生开销)和只有几个不同字母的字符串(如前所述)上表现不佳

    朴素搜索算法非常紧凑,循环内部的操作很少,所以循环运行速度很快。由于没有开销,它在搜索短字符串时表现更好。

    BM 算法的(与朴素搜索相比)相当复杂的循环操作每次循环运行需要更长的时间。这(部分)补偿了跳转表的积极性能影响。

    因此,尽管您使用的是长字符串,但小字母表(=小跳转表)会使 BM 表现不佳。 KMP 在循环中的开销较小(跳转表通常较小,但类似于带有小字母的 BM),因此 KMP 的性能非常好。

    【讨论】:

      【解决方案2】:

      简单的实现实际上对随机输入数据具有线性预期运行时间(与 BM/KMP 等相同)。我无法在这里写出完整的证明,但可以从算法设计技术和分析获得。

      大多数精确匹配算法都是天真的实现的优化版本,以防止被某些模式减慢。例如,假设我们正在搜索:

         aaaaaaaaaaaaaaaaaaaaaaaab
      

      在以下流上:

         aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab
      

      它在b 失败了很多次。 KMP/BM 实现旨在防止重复比较as。但是,如果序列本身是随机的,则几乎不可能出现这种情况,并且由于其较低的簿记开销或可能更好的空间/时间局部性,幼稚的实现可能会更好地工作。

      而且,是的,我不确定 DNA 序列是随机的。或者,它们中常见的重复。无论如何,如果没有代表性数据,就无法仔细检查。

      【讨论】:

      • 而且,是的,我不确定 DNA 序列是随机的。或者,它们中常见的重复。无论如何,如果没有代表性数据,就无法仔细检查。
      • 如果文本(干草)相当长,针不太短和字母表(即不同字符的数量很大),所有这些智能字符串匹配算法的性能都比简单匹配更好。因此,即使是随机字符串也会表现良好,因为获得良好移位值的概率随着字母大小和针长度的增加而增加。
      【解决方案3】:

      理论上好的算法(较低的时间复杂度)通常具有很高的记账成本,对于小问题规模的幼稚算法可能会不堪重负。实施细节也很重要。通过优化实现,您有时可以将运行时间提高 2 倍或更多。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-03-02
        • 1970-01-01
        • 2011-03-12
        • 1970-01-01
        • 2010-12-18
        • 2012-01-24
        • 1970-01-01
        相关资源
        最近更新 更多