【发布时间】:2016-02-04 11:18:19
【问题描述】:
在最终了解了 KMP 算法之后,它的复杂性仍然不清楚。 对于模式 M 的长度和文本 N 的长度,我知道,在最坏的情况下,它是 O(N+M) (仍然无法解释,为什么),但为什么平均是 O(N)案子? 提前感谢您的帮助。
【问题讨论】:
标签: case time-complexity knuth-morris-pratt
在最终了解了 KMP 算法之后,它的复杂性仍然不清楚。 对于模式 M 的长度和文本 N 的长度,我知道,在最坏的情况下,它是 O(N+M) (仍然无法解释,为什么),但为什么平均是 O(N)案子? 提前感谢您的帮助。
【问题讨论】:
标签: case time-complexity knuth-morris-pratt
在这个答案中,我将解决你问题的这一部分。
对于模式 M 的长度和文本 N 的长度,我知道,在 最坏的情况是 O(N+M)(仍然无法解释,为什么)
我将尝试解释为什么计算失败函数(KMP算法中的预处理步骤)需要线性时间,您可以对算法的字符串匹配部分的运行时间进行类似的分析。
代码(取自here):
KNUTH-MORRIS-PRATT 失败 (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 = 模式的长度。
成功匹配次数 (例如,检查这种模式“aaaa”)
我们称这个语句为 (2)
不成功的匹配次数有点棘手。
我们以模式“aaabcaaabce”为例
对于这个模式,数组是:
| 0 | 1 | 2 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 0 |
请注意,在索引 3 中,当发生不匹配时,当我们下降到值 0 时,我们最多可以做 2 个不匹配,或者换句话说,我们只能做与到目前为止匹配的字符数一样多的不匹配。
所以每次在索引 i 处发生不匹配时,该索引 i 处的最大不匹配数最多可以是迄今为止匹配的字符数(在索引 i-1 处)。
直观地说,在整个数组中匹配的字符数就是数组中非零的条目。因为非零条目意味着匹配。因为,
最大不成功匹配数 = 匹配字符数
=> 整个数组的最大不成功匹配数
= 数组中的最大字符匹配数
= 数组中非零的条目数
因此,数组中不成功匹配的最大数量
我们称这个语句为 (3)
将 (1)、(2) 和 (3) 放在一起:
总运行时间 = 成功匹配的运行时间 + 不成功匹配的运行时间
运行时间
运行时间
计算失败函数的运行时间 = O(N)
【讨论】: