KMP简介
关于啥是KMP 算法,还是去看大神的博客吧,他实在是写的太好了
阮一峰——字符串匹配的KMP算法
膜归膜,但是他所说的部分匹配表中的下标和各大参考书都格格不入。
为了应试需求,还是改成了我理解上的next数组(我们的教科书上叫这玩意儿失效函数,都是一个东西)。
KMP算法——NEXT数组
这是一道作业题:
求S=“abcaabbabcabaacbacba”失效函数的值
[-1, 0, 0, 0, 1, 1, 2, 0, 1, 2, 3, 4, 2, 1, 1, 0, 0, 1, 0, 0]
当然,这个太长了,不方便我们阐释
命S=“ abcdabcy”
那么失效函数,如果要手写的话,第一个肯定是“-1”<阮一峰里面写的就不是这样>
然后,abcd一定都是-1000,第二个a出现,这时候是0,之后的bc就是12,y则对应3。
就有了 [-1, 0, 0, 0, 0, 1, 2, 3]
那么如果用程序实现呢?
def pipeizhi(p):
# abcdabcy
# next函数偏移表next[]:-1 0 0 0 0 1 2 3
j = 0
k = -1
next = [-1]
for i in range(1, len(p)):
next.append(0) # 先指定一个next数组为[-1,0,0,0...]
try:
while (j < len(p) - 1):
if k == -1 or p[j] == p[k]:
# 如果找到了,那就开始滑动。j 遍历的事数组下标,而k则是为偏离表赋值的。画个图可能更加好理解
j += 1
k += 1
next[j] = k
else:
k = next[k]
except IndexError:
print next, k, j # 不可能错的放心
return next
KMP 算法的实现
现在,有了next数组,就可以为所欲为了:
def KMP(s, t): #s是目标船 ,t是模式串
slen = len(s)
tlen = len(t)
if slen >= tlen:
i = 0
j = 0
next = pipeizhi(t)
# print next
while i < slen: #开始遍历
print [i,j]
if j == -1 or s[i] == t[j]:
#i是遍历,j是目标串中找到的模式串中前面一部分的长度。
i += 1
j += 1
else:
j = next[j]
if j == tlen:
return i - tlen
return -1 #-1就是没有找到啊