【问题标题】:Why is the normal case complexity of KMP O(N)?为什么 KMP O(N) 的正常情况复杂度是?
【发布时间】:2016-02-04 11:18:19
【问题描述】:

在最终了解了 KMP 算法之后,它的复杂性仍然不清楚。 对于模式 M 的长度和文本 N 的长度,我知道,在最坏的情况下,它是 O(N+M) (仍然无法解释,为什么),但为什么平均是 O(N)案子? 提前感谢您的帮助。

【问题讨论】:

    标签: case time-complexity knuth-morris-pratt


    【解决方案1】:

    在这个答案中,我将解决你问题的这一部分。

    对于模式 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)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-13
      • 2012-09-12
      • 1970-01-01
      • 2017-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-24
      相关资源
      最近更新 更多