【问题标题】:(with example) Why is KMP string matching O(n). Shouldn't it be O(n*m)?(示例)为什么 KMP 字符串匹配 O(n)。不应该是 O(n*m) 吗?
【发布时间】:2019-11-03 01:24:20
【问题描述】:

为什么 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--)  {
    }
}

并把所有可能的 i j 组合也称为状态将需要一个 nm 数组,所以运行时不会是 O(nm)。

那么是我的代码读错了,还是for循环的运行时分析错了,还是我的例子不可能?

【问题讨论】:

    标签: algorithm time-complexity string-matching knuth-morris-pratt


    【解决方案1】:

    其实,现在想想。它是 O(n+m)。只是将其可视化为两个窗口移动。

    【讨论】:

    • n大于等于m,O(n+m) = O(n)
    猜你喜欢
    • 2019-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多