在最终理解了KMP算法之后,其复杂性仍不清楚。 对于模式M的长度和文本N的长度,我知道,在最坏的情况下它是O(N + M)(仍然无法解释,为什么),但为什么它在平均值为O(N)案件? 提前感谢您的帮助。
答案 0 :(得分:0)
在这个答案中,我将解决你问题的这一部分。
对于模式M的长度和文本N的长度,我知道,在 最坏的情况是O(N + M)(仍然无法解释,为什么)
我将尝试解释为什么计算失败函数(KMP算法中的预处理步骤)需要线性时间,并且您可以对算法的字符串匹配部分的运行时间使用类似的分析。
代码(取自here):
KNUTH-MORRIS-PRATT FAILURE(P)
Input : Pattern with N characters
Output: Failure function f for pattern P
i ← 1
matched ← 0
f(0) ← 0
while i < N do
if P[matched] = P[i]
f(i) ← j +1
i ← i +1
matched← matched + 1
else if matched>0
matched ← f(matched - 1)
else
f(i) ← 0
i ← i +1
计算失败函数的运行时间= while循环的最大迭代次数。
while循环的迭代次数=成功匹配的次数+ 不成功的比赛次数
我们称之为声明(1)
设N =模式的长度。
成功比赛次数&lt; = N
(例如,检查这种模式“aaaa”)我们称之为声明(2)
不成功的比赛数量有点棘手。
让我们举一个例子模式“aaabcaaabce”
对于此模式,数组为:
| 0 | 1 | 2 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 0 |
请注意,在索引3中,当发生不匹配时,当我们下降到0时,我们最多可以做2次不匹配,换句话说,我们只能做到与到目前为止匹配的字符数一样多的不匹配。
因此,每次在索引i处发生不匹配时,该索引处的最大不匹配数i最多可以是到目前为止匹配的字符数(在索引i-1处)。
直观地说,在整个数组上匹配的字符数只是数组中非零的条目。因为非零条目意味着匹配。从那以后,
不成功匹配的最大数量=匹配的字符数
=&GT;整个阵列上不成功匹配的最大数量
=数组上的最大字符匹配数
=数组中非零的条目数
&lt; = N
因此,数组上的最大不成功匹配数&lt; = N
我们称之为声明(3)
将(1),(2)和(3)放在一起:
总运行时间=成功匹配的运行时间+不成功匹配的运行时间
运行时间&lt; = N + N
运行时间&lt; = 2 * N
计算失败函数的运行时间= O(N)