O(N)中字符串中子串的出现次数

时间:2016-11-19 20:50:09

标签: algorithm string-matching aho-corasick

我想知道如何在线性时间内计算大海捞针中每根针的出现次数。我以为我会使用Aho-Corasick算法,但我不希望时间复杂度取决于针的出现次数。

2 个答案:

答案 0 :(得分:1)

如果要搜索一组字符串并且不想依赖于出现的次数,请使用Rabin–Karp。其平均/最佳案例运行时间为O(n + m),但其最坏情况时间为O(nm),其中n为文本长度,m为搜索模式的组合长度。

如果您只想搜索一个字符串,则可以使用复杂度为O(n + k)的{​​{3}},其中n为文本长度,k为搜索模式的长度。

答案 1 :(得分:0)

如果您只需要总出现次数(并且您不关心位置本身),则可以有效地使用Aho-Corasick。假设我们当前在节点v中。有多少子串在当前位置结束。我声称它正是通过后缀链接从v可到达的终端节点的数量。但后缀链接形成一棵树。因此,我们需要计算从后缀链接形成的树中v到根的路径上的终端顶点数。我们可以在O(1)时间进行线性预处理(例如,可以使用一次深度优先搜索,明确地构建此树并使用线性时间计算从根到任何顶点的路径上的总和)。我们也可以按正确的顺序处理顶点(例如,按照高度的递增顺序)并执行sum[v] += sum[suffix_link(v)]之类的操作。在这种情况下,我们甚至不需要实际构建此树。

这个算法明确地在输入大小的线性时间内工作(我们构建Aho-Corasick自动机并在线性时间内计算“后缀链路路径”的总和,然后我们像往常一样使用自动机)。