KMP算法可以在O(n+m)的时间数量级上完成模式匹配,其做法在于:没当一次匹配过程中出现字符比较不等时,不需要回溯指针,而是利用已经得到的“部分匹配”的结果将模式向右“滑动”尽可能远的一段距离后,继续进行比较。
在KMP算法中主要是先得到子字符串的next数组,比如子字符串为:abaabcac,计算如下图
得到子字符串之后,在字符串匹配的时候,子字符串不再是移动1个字符串,而是移动next(j)个位置,代码如:(这里需要注意,next数组是从1开始的,没有0)
#-*- coding:utf-8 -*- class KMP: def __init__(self,s_long,s_short): self.s_long=s_long self.s_short=s_short self.flag=0 def get_nextList(self): l=[0,1] for i in range(2,len(self.s_short)): l.append(self.get_num_1(self.s_short[0:i])) print l b=0 a=0 while True: if self.s_short[a]==self.s_long[b]: a+=1 b+=1 else: a=l[a]-1 if a==-1: a += 1 b += 1 if self.s_short==self.s_long[b:b+len(self.s_short)]: break if b==len(self.s_long): return 0 return b+1 ‘‘‘ 功能(见图2、3):获得子字符串的next数组,和第一张图方法比一样,更容易理解 s:用于存储该字符前面所有的子字符串(注意子字符串是从这个字符串开始从后往前,长度慢慢增长) while循环:用于确定前面最长重复的字符串(注意,应该从长的开始匹配,且必须从第一个字符开始) 返回最长字符串长度+1 ‘‘‘ def get_num_1(self,string): s=[] for i in range(1,len(string)): s.append(string[len(string)-i:len(string)]) while s: temp=s.pop() n=len(temp) if temp==string[0:n+0]: return len(temp)+1 return 1 long=raw_input() short=raw_input() print KMP(long,short).get_nextList()