KMP算法一开始看了很久都似懂非懂的,直到看了阮一峰大侠的博客http://blog.sae.sina.com.cn/archives/307 终于觉得看懂了,然后找了一个程序,
程序如下:
def compute_prefix_function(p):
m = len(p)
pi = [0] * m
k = 0
for q in range(1, m):
while k > 0 and p[k] != p[q]:
k = pi[k - 1]
if p[k] == p[q]:
k = k + 1
pi[q] = k
return pi
def kmp_matcher(t, p):
n = len(t)
m = len(p)
pi = compute_prefix_function(p)
q = 0
for i in range(n):
while q > 0 and p[q] != t[i]:
q = pi[q - 1]
print t
print ' '*(i-q) + p
print i,q
print '\n'
if p[q] == t[i]:
q = q + 1
if q == m:
return i - m + 1
return -1
以博文中提到的字符串为例:
t = "BBC ABCDAB ABCDABCDABDE"
p = "ABCDABD"
result = kmp_matcher(t, p)
打印结果:
BBC ABCDAB ABCDABCDABDE ABCDABD 0 0 BBC ABCDAB ABCDABCDABDE ABCDABD 1 0 BBC ABCDAB ABCDABCDABDE ABCDABD 2 0 BBC ABCDAB ABCDABCDABDE ABCDABD 3 0 BBC ABCDAB ABCDABCDABDE ABCDABD 4 0 BBC ABCDAB ABCDABCDABDE ABCDABD 5 1 BBC ABCDAB ABCDABCDABDE ABCDABD 6 2 BBC ABCDAB ABCDABCDABDE ABCDABD 7 3 BBC ABCDAB ABCDABCDABDE ABCDABD 8 4 BBC ABCDAB ABCDABCDABDE ABCDABD 9 5 BBC ABCDAB ABCDABCDABDE ABCDABD 10 0 BBC ABCDAB ABCDABCDABDE ABCDABD 11 0 BBC ABCDAB ABCDABCDABDE ABCDABD 12 1 BBC ABCDAB ABCDABCDABDE ABCDABD 13 2 BBC ABCDAB ABCDABCDABDE ABCDABD 14 3 BBC ABCDAB ABCDABCDABDE ABCDABD 15 4 BBC ABCDAB ABCDABCDABDE ABCDABD 16 5 BBC ABCDAB ABCDABCDABDE ABCDABD 17 2 BBC ABCDAB ABCDABCDABDE ABCDABD 18 3 BBC ABCDAB ABCDABCDABDE ABCDABD 19 4 BBC ABCDAB ABCDABCDABDE ABCDABD 20 5 BBC ABCDAB ABCDABCDABDE ABCDABD 21 6
刚开始觉得是错的,如,i在(10,16)之间时,A字符串没有挪动,像是在做重复的事情,后来仔细想想,实际执行过程就是这样的,字符匹配上时,i和q是同时移动的,一直移动到完全匹配成功或者匹配失败为止。