数据结构子KMP算法

传统从主串找子串方法

在这里插入图片描述
然子串从第一个开始,一个个比对,相同比对第二个字母
不同然子串后移一位重新开始比较
直至找到全部相同的或者主串里面没有让子串比较的字母了

这样的算法太暴力,执行效率太低

KMP算法

来说我们人脑对于字符串匹配的思考方式吧
从左往右直接扫
不会说回去再看一遍

那怎么让代码完成这样的操作呢?

在这里插入图片描述
那就是KMP算法喽

回溯子子串不回溯主串
在这里插入图片描述

直接右移五步
在这里插入图片描述
若11是g在这里插入图片描述
若11不是j
在这里插入图片描述

但是到底子串要从主串的哪个位置开始比较是不固定的
在这里插入图片描述
如果死第五个字母不匹配
要从第四个字母开始比较
而不是从不匹配的字母开始匹配了

那么如果比较失败到底从主串哪里重新开始匹配呢?

需要另外定义一个next数组看到第几个不匹配然后
在取对应数字next数组的元素
子串的对应位置开始再次比较
(因为主串指针不回溯,所以next里面是存放的是子串的位置)
在这里插入图片描述
j是指向子串的从1开始
i指向主串

对应代码

在这里插入图片描述
next[1]=0;
第一个位置就不同,使j=0
然后i++,j++
子串重新指到1
然后主串后一一位

那么如何求一个模式串的next数组呢?

求next数组

写两个子串
上面的子串做主串
下面算模式串
从主串的末位开始,从最后一个算匹配失败,看前面的能和模式串(就是本身)
能有几个匹配的,如果可以匹配上的话对应的next[子串匹配失败位置]=匹配成功字符+1

手算

当j=6匹配失败应该从第个开始?
就拿子串依次次往后移呗
看有没有可以和前面对应的
对应了i个那么next[j]=i+1

在这里插入图片描述
对应了(此时j还是6)
对应了2个那么next[6]=3
在这里插入图片描述
这个也是同理

在这里插入图片描述

总结(方法)

在这里插入图片描述

比如说下面
第7个字符匹配失败,然后把对应的第1-6字符组成一个字符串
看这个字符串前缀和对应上面1-6进行匹配
一定是看对应的
上面串的后缀

下面串的前缀
(上面不含头,下面不含尾)最长相等长度哦
(就是让下面的往右移直至到第一次相同,就是最长长度,不包含刚开始的时候)
如果都不匹配,那就是0+1=1呗

一些特殊情况

如果一开始就不匹配(第一个位置)
那么next[1]固定是0,这个情况下实行i++和j++

如果第二个不匹配
这个时候其实取
1-j-1元素那就是第一个元素
就一个元素
这个元素既是前缀又是后缀
但是要求不能包含下面串的后缀
所以
此时next[2]=1(固定的)

我的一些小方法

就是看第i个匹配失败
取出对应模式串1-i-1(取两次)
然后和自己比较
看1-i-1
比如
ababaa
第三匹配失败
取
ab
ab
上面取后缀,下面前缀
下面往右移
ab
  ab
还是不相同
ab
    ab
最后没有相同的,重新开始比较呗
next[3]=1
比如第四个失败
取的是
aba
aba
下面的开始右移
aba
  aba
不同
aba
    aba
此时对应位置相同了
则next[4]=1+1=2

在这里插入图片描述

在这里插入图片描述

代码实现

在这里插入图片描述

时间复杂度

在这里插入图片描述

进一步优化

在这里插入图片描述
例如这个情况
下一步就是把j=1

在这里插入图片描述

这个过程有没有感觉有一丝多余
因为你的子串第四个字符和第一个字符就相同
第四个不匹配
所以主串的对应字符不是g
所以你就算把j=1然后比较也肯定不相同
这就多了一次比较

对应优化
在这里插入图片描述

怎么求next_value

在这里插入图片描述
看左下角
首先有next数组
然后从左往右比
看从2开始看
第二个序号j的next
指向第一个字符(a)
但是它自己对应也是a
所以把对应第一个序号对应的数组(0)
赋给第二个序号对应的nextvalue
第三个也是
第四个也是
第五个的话对应的next为4
第四个字符和第五个字符不同
所以
保存对应的next到nextvalue
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小袁拒绝摆烂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值