关于KMP中的预处理表感到困惑

时间:2013-03-21 05:17:30

标签: string algorithm

查看KMP算法,并对KMP中计算后缀前缀计数表的特定行感到困惑。

算法kmp_table:     输入:         一个字符数组,W(要分析的单词)         一个整数数组,T(要填充的表)     输出:         什么都没有(但在操作过程中,它会填充表格)

define variables:
    an integer, pos ← 2 (the current position we are computing in T)
    an integer, cnd ← 0 (the zero-based index in W of the next 
    character of the current candidate substring)

(the first few values are fixed but different from what the algorithm 
might suggest)
let T[0] ← -1, T[1] ← 0

while pos is less than the length of W, do:
    (first case: the substring continues)
    if W[pos - 1] = W[cnd], 
      let cnd ← cnd + 1, T[pos] ← cnd, pos ← pos + 1

    (second case: it doesn't, but we can fall back)
    otherwise, if cnd > 0, let cnd ← T[cnd]

    (third case: we have run out of candidates.  Note cnd = 0)
    otherwise, let T[pos] ← 0, pos ← pos + 1

以上内容直接来自维基百科。如果cnd > 0为什么设置cnd := T[cnd],我有点困惑,不应该重新设置为0,好像我们重新开始一样?

1 个答案:

答案 0 :(得分:0)

显然,T[0] = -1因此将cnd设置为T[cnd = 0] = -1将等于在下一次迭代中读取W[cnd = -1]并且在字符串之外。至少出于这个原因,您需要对cnd > 0 vs cnd == 0进行特殊处理。

我们将cnd与0进行比较的真正原因是T[cnd]应该为W[]提供W[cnd]中的位置,当{的左侧部分字符串匹配时,它将倒回{1}}。但是,T[0]不能用于此目的,因为W[0]左侧没有任何内容。

  

为什么设置cnd:= T [cnd],不应该重置为0,就好像我们重新开始一样?

你错过了算法的全部要点。如果在部分匹配后在位置0重新启动,则回到初始算法。 T[]包含倒带位置,正如您从下面的W[]T[]的示例表中看到的那样,它们并不总是0.所以,不要一直回到位置0,你有时会去其他位置并从那里继续匹配。这就是使算法比天真算法更具可扩展性的原因。