[英]What's the worst case complexity for KMP when the goal is to find all occurrences of a certain string?
我还想知道哪种算法具有最差的案例复杂性,以便在另一个中查找所有出现的字符串。 似乎Boyer-Moore的算法具有线性时间复杂度。
KMP算法具有线性复杂性,用于查找字符串中所有出现的模式,如Boyer-Moore算法¹。 如果你试图在像“aaaaaaaaa”这样的字符串中找到像“aaaaaa”这样的模式,那么一旦你有了第一个完整的匹配,
aaaaaaaaa
aaaaaa
aaaaaa
^
边界表包含模式前缀的下一个最长可能匹配(对应于模式的最宽边界)的信息只有一个字符短(完全匹配相当于模式结尾之后的不匹配)这方面)。 因此,模式被进一步移动一次,并且由于从边界表中已知模式的所有字符除了可能的最后匹配之外,下一个比较是在最后一个模式字符和对齐的文本字符之间。 在这种特殊情况下(在n中发现m的出现),这是天真匹配算法的最坏情况,KMP算法将每个文本字符恰好比较一次。
在每一步中,至少有一个
增加,并且从未减少。 比较文本字符的位置最多可以增加length(text)-1
次,第一个模式字符的位置最多可以增加length(text) - length(pattern)
次数,因此算法最多需要2*length(text) - length(pattern) - 1
步。
预处理(边界表的构造)最多需要2*length(pattern)
步骤,因此总体复杂度为O(m + n),如果m
是模式的长度,则不再执行m + 2*n
步骤和n
文本的长度。
¹请注意,如果需要所有匹配,通常呈现的Boyer-Moore算法对于周期性模式具有O(m * n)的最坏情况复杂度,并且如果需要所有匹配则具有m和n的文本,因为在完全匹配之后,
aaaaaaaaa
aaaaaa
aaaaaa
^
<- <-
^
整个模式将被重新比较。 为避免这种情况,您需要记住在完全匹配后移位后模式的前缀仍然匹配多长时间,并且仅比较新字符。
关于KMP的文章很长,请访问http://en.wikipedia.org/wiki/Knuth-morris-pratt ,最后说的是
由于算法的两个部分分别具有O(k)和O(n)的复杂度,因此整个算法的复杂度为O(n + k)。
无论W或S中有多少重复模式,这些复杂性都是相同的。(最终引用)
因此,KMP搜索的总成本在字符串和模式的字符数中是线性的。 即使你需要在字符串中找到多次出现的模式,我认为这仍然存在 - 如果不是,只需要考虑搜索patternQ,其中Q是文本中没有出现的字符,并记下KMP状态显示的位置它已经匹配到Q的一切。
您可以在O(length)
计算字符串的Pi函数。 KMP构建一个长度为n+m+1
的特殊字符串,并在其上计算Pi函数,因此无论如何复杂度为O(n+m+1)=O(n+m)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.