查看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,好像我们重新开始一样?
答案 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,你有时会去其他位置并从那里继续匹配。这就是使算法比天真算法更具可扩展性的原因。