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

Algorithm O(N)中字符串中出现的子字符串数,algorithm,string-matching,aho-corasick,Algorithm,String Matching,Aho Corasick,我想知道如何在线性时间内计算大海捞针发生的次数。我想我会使用Aho-Corasick算法,但我不希望时间复杂度取决于针的出现次数。如果要搜索一组字符串并且不希望依赖于出现次数,请使用。它的平均/最佳情况运行时间是O(n+m),但最坏情况运行时间是O(nm),其中n是文本长度,m是搜索模式的组合长度 如果只想搜索一个字符串,可以使用复杂度O(n+k),其中n是文本长度,k是搜索模式的长度 如果您只需要事件总数(而不关心位置本身),可以高效地使用Aho。让我们假设当前处于节点v。有多少子字符串在当前

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

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


如果只想搜索一个字符串,可以使用复杂度
O(n+k)
,其中
n
是文本长度,
k
是搜索模式的长度

如果您只需要事件总数(而不关心位置本身),可以高效地使用Aho。让我们假设当前处于节点
v
。有多少子字符串在当前位置结束。我声称这正是通过后缀链接从
v
可以访问的终端节点的数量。但是后缀链接形成一棵树。因此,我们需要计算从
v
到后缀链接形成的树的根的路径上的终端顶点数。我们可以通过线性预处理在
O(1)
时间内完成这项工作(例如,可以显式地构建这棵树,并使用一次深度优先搜索计算从根到线性时间内任何顶点的路径上的和)。我们还可以按正确的顺序处理顶点(例如,按高度的增加顺序),并执行类似于
sum[v]+=sum[suffix\u link(v)]
的操作。在这种情况下,我们甚至不需要实际构建这棵树


该算法在输入大小的线性时间内显然有效(我们构建Aho-Corasick自动机,并在线性时间内计算“后缀链接路径”上的和,然后像通常一样使用自动机)。

子字符串是否固定?也就是说,您需要计算固定字符串S在固定字符串T中出现的次数吗?这是我的错误,它是用于多针的,现在应该是正确的。我相信您的方法也可以用于查找出现的位置。可以在后缀链接树中进行Euler漫游,并执行平方根分解。这样,您将得到O(n*sqrt n)中的答案。