九分钟带你弄懂KMP算法【数理篇】

前言

        我将KMP算法的详解分为三个篇章:

         【原理篇】:主要讲解KMP实现的原理,以及手动求NEXT数组。

      ->【数理篇】:主要讲解如何在手动求出NEXT数组的情况下,找出数学规律,为之后的算法实现奠定基础。

         【实现篇】:主要讲解以C语言代码的方式实现KMP算法,以及NEXT数组的优化。

        其余篇章将在之后更新

🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈

  制作不易,若对你有帮助的话点赞、关注、评论走一波,你们的支持是我前进路上最大的动力。

前情提要:

        在原理篇当中我已经讲解了KMP中最核心的NEXT数组,以及他的求法:NEXT[j]存储了从PAT[0]到PAT[j-1]位置,以PAT[0]为首,PAT[j-1]为结尾的两个最长子字符串的长度位(可以重叠,但不能相等)。忘记的朋友们可以看看之前的篇章。

数理篇正式开始:

012345678910
PAT字符串abcababcabc
NEXT数组-10001212345

现在有这样一个NEXT数组,除了NEXT[0]与NEXT[1]是已经规定好的-1和0之外,其余的都要我们手动去求。在上一个篇章当中,我们学会了如何用手去求NEXT数组。但在实际生产过程当中,这种方法肯定是不可取的,那么NEXT数组的构成当中有什么规律呢

我们先假设在NEXT数组当中,有两个指针,一个叫i一个叫k。

设有NEXT[i]=k,也就是可以通过NEXT数组的下标去访问K指针所在的位置,这一假设是以下的推论的大前提。

此时就有p[0]--p[k-1](以首元素为头的子字符串)=p[x]--p[i-1](以i-1为尾的子字符串)这两个字符串相同,疑惑为什么相同的朋友们可以去看看NEXT数组的定义。那这里的X从哪里来的呢?

x是为了之后的推导,先假设出来的,如果不解继续往下看~

因为两字符串长度相同(定义),所以就存在关系 k-1-0=i-1-x,也就可以推导出x=i-k

此时再将x放回上文的推导关系,就有这样的一个关系p[0]--p[k-1]=p[i-k]--p[i-1]

情况1:PAT[i]=PAT[K]

当PAT[i]=PAT[K]时,也就是对应的两个字符相同,可以参考上图中i k对应的位置。又因为

p[0]--p[k-1]=p[i-k]--p[i-1],p[i]=p[k](字符相同),所以就有p[0]--p[k]=p[i-k]--p[i],

又因为从next[i]=k可以推导出p[0]--p[k-1]=p[i-k]--p[i-1],那么是不是p[0]--p[k]=p[i-k]--p[i]可以反向推导出next[i+1]=k+1!

那么也就可以得出情况一的结论:

在PAT[i]=PAT[k]的情况下,NEXT[i+1]=k+1。

那如果PAT[i]!=PAT[k]呢?那这就是我们的情况2

情况2:PAT[i]!=PAT[K]

那就非常简单粗暴了,k=NEXT[k],也就是一直往回退直到满足PAT[i]=PAT[k]这一情况时,在继续套用情况一进行推导。如图,此时PAT[i]!=PAT[K],那么,就令k=NEXT[k],也就是移动到,p[0]的位置,此时满足情况1PAT[i]=PAT[K],所以此时的NEXT[i+1]=k+1,也就是NEXT[4]=1。

 若退回到0位置时还不相等呢?那继续往下退到-1岂不是越界了?这里可以加一个判定,若退到0还不满足,可以直接令NEXT[i+1]=0(-1+1),具体实现可以关注我下一篇KMP代码实现的讲解。

 

至此,本篇博客的内容九分钟带你弄懂KMP算法【数理篇】告一段落,若对你有些许帮助,可以点赞、关注、评论支持下博主,你的支持将是我前进路上最大的动力。

若以上内容有任何问题,欢迎在评论区指出。若对以上内容有任何不解,都可私信评论询问。

诸君,山顶见!

🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈​​​​​​​

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ppeua

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

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

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

打赏作者

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

抵扣说明:

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

余额充值