KMP算法


categories: 算法
tags:

  • python
  • kmp

为什么用ta

kmp一个效率非常高的字符串匹配算法。
有问题如下:

#求b在a中出现次数
a = "ababacababadababadadda"
b = "ababad"

kmp可以将暴力法的O(m*n)降低为O(m+n)

该怎么用ta

  1. 计算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 first a can match the fourth a

  1. 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

小结

利用已匹配的信息,迈出比较大的步子。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值