KMP算法学习记录

一、KMP算法解决的问题:

        KMP算法主要解决字符串匹配的问题;当遇到冲突的字符时候,由于前缀表记录了之前的匹配信息,因此模式串不需要从头开始匹配;(从文本串中寻找模式串)

二、KMP算法的核心:

        KMP算法的核心是找到前缀表(前缀表中存储了第i个索引以及其之前的子串的最大相等前后缀),然后利用前缀表进行回退

        当匹配到某个字符发生冲突时,找到其前一个字符在前缀表中(next数组中)对应索引位置处的值,然后模式串索引回退到指定位置,重新开始匹配。

三、最大相等前后缀

        前缀:不包含末尾字符的所有子串;

        后缀:不包含首字符的所有子串;

        例如:a 的最大相等前后缀为0;aa的最大相等前后缀为1;aab的为0;aaba的为1;aabaa的为2;

四、前缀表的求解

        1.程序需要处理三种情况:初始化、当前后缀相同的情况、前后缀不相同的情况;具体实现看代码;

        2.有了前缀表之后就可以进行匹配了;

五、KMP算法解决leetcode 28

        1.题目描述:

        leetcode链接:https://leetcode-cn.com/problems/implement-strstr/

        2.代码

class Solution:
    #获取前缀表(next数组)
    def getNext(self,s):
        next_lst = [0]*len(s)
        qz = 0 
        next_lst[0] = qz    
        for hz in range(1,len(s)):
            #前后缀不相等的情况
            while s[qz]!= s[hz] and qz>0:
                #回退
                qz = next_lst[qz-1]
            if s[qz] == s[hz]:
                #前后缀相等的情况
                qz +=1
                #前缀的索引+1就是当前后缀及其前面字符串的最大相等前后缀
                next_lst[hz] = qz
        return next_lst

    def strStr(self, haystack: str, needle: str) -> int:
        if len(needle) ==0:
            return 0
        needle = list(needle)
        haystack = list(haystack)
        next_lst = self.getNext(needle)     #获取到next数组
        #进行比较
        i,j=0,0
        while i<=len(haystack)-1 and j<=len(needle)-1:
            #终止条件,只要任意一个数组遍历完就中止,终止后判断如果是模式串遍历完成,则说明文本串中存在模式串,否则输出-1
            if haystack[i] == needle[j]:
                j+=1
            else:
                #如果j小于1则j为0
                if j>=1:
                    j = next_lst[j-1]
                    i -=1       #遇到矛盾的字符串,i不动,j回退,但由于if语句之外有个i+=1,因此这里减去1
                else:
                    j = 0
            i +=1
        #终止后判断
        if j==len(needle):
            return i-j 
        else:
            return -1
        

六、参考 

        KMP算法详解参考:

        B站大佬Carl讲解

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值