为什么 KMP O(n + m)?
我知道这个问题可能已经在这里被问了一百万次,但我还没有找到一个让我/我理解的解决方案或一个与我的例子相匹配的问题。
/**
* KMP algorithm of pattern matching.
*/
public boolean KMP(char []text, char []pattern){
int lps[] = computeTemporaryArray(pattern);
int i=0;
int j=0;
while(i < text.length && j < pattern.length){
if(text[i] == pattern[j]){
i++;
j++;
}else{
if(j!=0){
j = lps[j-1];
}else{
i++;
}
}
}
if(j == pattern.length){
return true;
}
return false;
}
n = 文本
大小 m = 图案大小
我知道为什么它的 + m,这就是创建 lsp 数组进行查找所需的运行时。我不确定为什么我上面传递的代码是 O(n)。
我看到上面的“i”总是向前推进,除非它不匹配并且 j!= 0。在这种情况下,我们可以在 i 不向前移动的情况下进行 while 循环的迭代,所以它不完全是 O(n )
如果 lps 数组像 [1,2,3,4,5,6,0] 一样递增。如果我们在索引 6 处匹配失败,j 会更新为 5,然后是 4,然后是 3.... 等等,我们有效地经历了 m 次额外的迭代(假设所有不匹配)。这可能发生在每一步。
所以看起来像
for (int i = 0; i < n; i++) {
for (int j = i; j >=0; j--) {
}
}
并且将所有可能的 ij 组合也称为状态将需要一个m 数组,因此运行时不会是 O(n m)。
那么是我的代码读错了,还是for循环的运行时分析错了,还是我的例子是不可能的?