String 什么';当目标是查找某个字符串的所有匹配项时,KMP的最坏情况复杂度是多少?

String 什么';当目标是查找某个字符串的所有匹配项时,KMP的最坏情况复杂度是多少?,string,algorithm,time-complexity,knuth-morris-pratt,String,Algorithm,Time Complexity,Knuth Morris Pratt,我还想知道哪种算法在查找另一个字符串中出现的所有字符串时具有最坏的情况复杂性。似乎是Boyer–Moore的算法具有线性时间复杂度。您可以在O(长度)中为字符串计算Pi函数。KMP构建了一个长度为n+m+1的特殊字符串,并对其上的Pi函数进行计数,因此在任何情况下,复杂性都将是O(n+m+1)=O(n+m)关于KMP的一篇长篇文章以 由于算法的两部分分别具有O(k)和O(n)的复杂性,因此整个算法的复杂性为O(n+k) 无论W或S中有多少重复模式,这些复杂性都是相同的。 (完) 因此,KMP搜索

我还想知道哪种算法在查找另一个字符串中出现的所有字符串时具有最坏的情况复杂性。似乎是Boyer–Moore的算法具有线性时间复杂度。

您可以在
O(长度)
中为字符串计算Pi函数。KMP构建了一个长度为
n+m+1
的特殊字符串,并对其上的Pi函数进行计数,因此在任何情况下,复杂性都将是
O(n+m+1)=O(n+m)

关于KMP的一篇长篇文章以

由于算法的两部分分别具有O(k)和O(n)的复杂性,因此整个算法的复杂性为O(n+k)

无论W或S中有多少重复模式,这些复杂性都是相同的。 (完)


因此,KMP搜索的总成本与字符串和模式的字符数成线性关系。我认为,即使你需要在字符串中找到多个模式的出现,如果不是,只考虑搜索TypNQ,Q是文本中不出现的字符,记下KMP状态显示它已将所有内容匹配到Q。

KMP算法具有线性复杂度,用于查找字符串中所有出现的模式,如Boyer-Moore算法。如果您试图在“aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

aaaaaaaaa
aaaaaa
 aaaaaa
      ^
aaaaaaaaa
aaaaaa
 aaaaaa
      ^
  <- <-
 ^
border表包含以下信息:模式前缀的下一个最长可能匹配(对应于模式的最宽边框)仅短一个字符(在这方面,完全匹配相当于超过模式末尾的不匹配匹配)。因此,模式被进一步移动一个位置,并且由于从边框表知道模式的所有字符可能除了最后一个匹配之外,下一个比较是在最后一个模式字符和对齐的文本字符之间。在这种特殊情况下(查找am在an中的出现),这是朴素匹配算法的最坏情况,KMP算法会对每个文本字符进行一次精确的比较

在每个步骤中,至少有一个

  • 比较的文本字符的位置
  • 模式的第一个字符相对于文本的位置
会增加,但不会减少。所比较的文本字符的位置最多可以增加
length(text)-1
次,第一个模式字符的位置最多可以增加
length(text)-length(pattern)
次,因此算法最多需要
2*length(text)-length(pattern)-1
步数

预处理(构建边框表)最多需要
2*length(pattern)
步骤,因此总体复杂度为O(m+n),如果
m
是模式的长度,
n
是文本的长度,则不再执行
m+2*n
步骤

⑨注意,通常提出的Boyer-Moore算法对周期模式和文本(如am和an)的最坏情况复杂性为O(m*n),因为在完全匹配之后

aaaaaaaaa
aaaaaa
 aaaaaa
      ^
aaaaaaaaa
aaaaaa
 aaaaaa
      ^
  <- <-
 ^
aaaaaaaaaaaa
AAAAA
AAAAA
^

你能提供更多的细节吗?你可以在这里查一下,这不是很清楚。假设我想使用KMP查找“aaaaa”中出现的“aaa”,KMP不需要进行n*m比较来查找所有出现的情况吗?它将进行O(3+8),这意味着(3+8)*一些常量KMP通过记住到目前为止匹配了多少个字符来避免比较。在看到并匹配aaa后,它知道要搜索的字符串的最后3个字符是aaa,因此当它看到后面紧跟着另一个a时,它知道这也是与包括新匹配aaa在内的最后三个字符的匹配。这不在Wikipedia代码中,该代码在匹配时返回。如果使用aaaQ技巧,KMP将知道它有aaa,并且应该转到代表aa的状态,找到角色!=Q是a,然后再转到aaa状态。