categories: 算法
tags:
- python
- kmp
为什么用ta
kmp一个效率非常高的字符串匹配算法。
有问题如下:
#求b在a中出现次数
a = "ababacababadababadadda"
b = "ababad"
kmp可以将暴力法的O(m*n)
降低为O(m+n)
该怎么用ta
- 计算temp数组
temp数组可理解为一组b中相同前后缀的标记(不能为本身长度)
b = "ababad"
对第一位'a'
,没有相同前后缀,temp[0] = 0
对第二位'ab'
,temp[1] = 0
对第三位’aba'
,temp[2] = 1
以此类推,temp= [0,0,1,2,3,0]
def cal_temp(b):
#K是一个对相同前后缀的标记
temp,k=[0],0
#从索引1处开始遍历
for i in range(1,len(b)):
while k>0 and b[i]!=b[k]:
k=temp[k-1]
if b[i]==b[k]:
k+=1
temp.append(k)
return temp
分析一下代码:
i=1
时,’ab’,b[1]!=b[0],temp.append(0)i=2
时,‘aba’,b[2]==b[0],temp.append(1)i=3
时,‘abab’,b[3]==b[1],temp.append(2)i=4
时,‘ababa’,b[4]==b[2],temp.append(3)i=5
时,‘ababad’,temp=[0,0,1,2,3]
b[5]!=b[3],k=temp[3-1]=1
b[5]!=b[1],k=temp[1-1]=0
temp.append(0)
发现比较难理解的是那个回溯的地方:k=temp[k-1]
没事,把i=5
的情况再分析一下:
i=5
时,‘ababad’,temp=[0,0,1,2,3],k=3
aba and aba can match,k=3
a and a can match,k=(aba的匹配数1,即temp[k-1])
more explain: aba can see as a and a,the firsta
can match the fourtha
- kmp
打完上面的怪,就可以直接写kmp了
def kmp(a,b):
temp=cal_temp(b)
ans,k=0,0
for i in range(len(a)):
while k>0 and a[i]!=b[k]:
k=temp[k-1]
if a[i]==b[k]:
k+=1
if k==len(b):
ans+=1
k=temp[k-1]
return num
小结
利用已匹配的信息,迈出比较大的步子。