KMP模式匹配算法的时间复杂度可以是O(m * n)?

时间:2017-02-26 14:52:05

标签: string algorithm pattern-matching

我在这里看到的答案很少,但仍需要一些澄清。 KMP的最坏情况时间复杂度为O(n+m)。但我理解的是,在最坏的情况下它应该是O(n*m)。让我们举一个例子:

string(n):  aaaaaaaaa
pattern(m): aaab

前3个字符匹配。然后是不匹配。 "aaa"的正确前缀后缀表将返回2.因此,根据KMP,只能(3-2)= 1个字符移动。所以我们比较n*(m-1)次才能得出结论,在这种情况下没有匹配。有效的时间复杂度为O(n*m)

在这种情况下,有人可以解释它是O(m+n)。我是否必须考虑除正确的前缀后缀表之外的任何其他内容并将其视为特殊情况。是在KMP中提到的吗?这个特定场景的详细解释非常有用。

1 个答案:

答案 0 :(得分:3)

  

因此,根据KMP,只能(3-2)= 1个字符移动。

  

所以我们比较n *(m-1)次才能得出结论在这种情况下没有匹配。

没有。 接下来我们比较的是a(文本的第4个)与a(模式的第3个),它给出2 + 1 = 3作为当前匹配的长度。

让我们使用T = aaaaaaaaa文本和P = aaab模式示例。

  • 在位置1,我们有T [1] = P [1],所以匹配的长度是1.
  • 在位置2,我们有T [2] = P [2],所以匹配的长度是2.
  • 在位置3,我们有T [3] = P [3],所以匹配的长度是3.
  • 在位置4,我们有T [4]≠P [4]。 匹配的长度减少到pref(3)= 2(负步)。
  • 再次在第4位,我们有T [4] = P [3],所以比赛的长度是3。
  • 在位置5,我们有T [5]≠P [4]。 匹配的长度减少到pref(3)= 2(负步)。
  • 再次在第5位,我们有T [5] = P [3],所以匹配的长度为3。
  • 等等。

如您所见,从第4位开始,对于每个位置,我们分两步而不是一步。 但我们不是在任何时候比较子串,只是单个字符。 位置数为| T |,负步数最多为| T |,因此总步数相对于| T |是线性的。