KMP算法以及next数组(详细易懂版)

今天也是学习了KMP算法,由于next数组有三种模型,刚开始让我很是错乱,因为当时不知道,后来才发现原来next数组的版本有三种,让我纠结了好久,下面是next数组的三种模型。

刚开始我学的是第一种,那个是最大前缀,求next数组的时候应该不复杂,到时到kmp主函数的时候可能会变复杂,这一种我是在知乎上看到的,这位博主讲的很好,我直接理解了kmp的原理以及最大前缀的作用,链接如下:(4 封私信 / 56 条消息) 如何更好地理解和掌握 KMP 算法? - 知乎 (zhihu.com)

但是这位博主的编程语言用的是python,而我没有学过python,看着确实不舒服,于是乎我又在csdn上找了几篇文章,随后我看到了一篇好文章,这篇文章讲解的是第二种next数组,也是最常用的一个版本,讲的很好,我本来不愿舍弃刚理解的第一种,不过这种算法还是大众常用的比较好:(69条消息) KMP算法图文详解(为什么是next[0]=-1、next[j]=k和k=next[k])_快乐江湖的博客-CSDN博客_kmp算法

这位博主写的代码确实让我收获了不少,对于kmp也是增进了很多理解,总算学会了,下面是我对代码的一些理解,原理大家就看上面的两篇文章吧

class Solution {
public:
int* kmp(string str)
   {
     int* next = new int[str.size()];
     int k = -1;//这里k==-1,是为了和第十行和第15行相呼应,好进行回溯。
     int j = 0;
     next[0] = -1;//next==-1也是与15行相呼应,能够进行回溯的处理。
     while(j<str.size()-1){
         if(k == -1||str[j] == str[k]){//这里是让j动起来如果相等的话就同时前进
             j++;
             k++;
             next[j] = k;//对next数组进行赋值,注意我是第二种next数组
         }
         else k = next[k];//这里是回溯
     }
     return next;
   }

    int strStr(string haystack, string needle) {
        if(haystack.size()<needle.size()){
            return -1;
        }
        int* next = new int [haystack.size()];
        int i = 0;
        int j = 0;
        int sum = needle.size();//这里我建立了一个变量,因为.size()不能直接与负数比较
//这点我写题目的时候困扰了好久找不出问题,后来还是一直调试才发现j==-1时while函数就不进入循环了
        next = kmp(needle);
        while(i<haystack.size()&&j<sum){
            if(j==-1||haystack[i]==needle[j]){//这里跟next数组的建立有异曲同工之妙
//很类似,大家可以编写两个字符串来验证这个流程,在一步一步的迭代中你们就会慢慢懂得这一串代码
//为什么这样写了
                i++;
                j++;
            }
            else j = next[j];//回溯
        }
        if(j>=needle.size()){
            return i-needle.size();//这里是返回下标
        }
        else return -1;//未找到返回-1;
    }
};

总的来说算法这种东西,你会了就真的觉得简单,不会就会觉得很难,但是只要你肯花时间,我相信再难也可以搞懂的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小A敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值