彻底弄懂408——数据结构中Next与Nextval数组的求取问题

本文只讲如何求解字符串的Next与Nextval数组,和如何利用这两个数组,至于为什么这样求解不做过多解释,也没有必要花很多时间去了解。掌握选择题的解题思路即可,代码部分不是特别重要
1.KMP算法简介
朴素模式匹配算法在字符串对比失败后,主串指针会回溯到之前开始位置的下一位,继续进行对比,回溯导致了字符串对比的时间复杂度很高,接近O(n^2)。
在这里插入图片描述
KMP的主要思想是避免主串回溯,当发生对比失败时,移动模式串对比指针的位置而保持主串的对比指针不动,从之前对比失败的位置继续对比(特别的:当模式串首位发生对比失败时,主串指针往下移动一位,模式串继续从首位开始与其对比),直至找到主串中和模式串一样内容的串或主串对比完全结束
在这里插入图片描述
2.Next数组引入
上文讲到,KMP的思想是移动模式串指针从而在匹配中尽可能减少主串对比指针的回溯,达到加快匹配速度的效果。那么当模式串与主串发生对比失败时,我们应该怎么移动模式串的指针?这里就要引入Next数组,给模式串的每个字符都配置一个数字,当该字符出现对比失败时,根据该数字移动模式串指针,这些数字一起就构成了Next数组:
在这里插入图片描述
如上图所示,当l字符发生对比失败时,I对应的Next[5]=2,因此此时要将模式串的指针移动到模式串的第二个字符O处,从这里继续对比模式串与主串。注意:当模式串首位的g字符对比失败时,因为其next数组的数字为0,而模式串字符的位序从一开始计数,因此此时要移动主串的指针到下一位,模式串的指针回到其首位,再继续对比,代码实现参照如下代码:
在这里插入图片描述
3.Next数组求解
next数组的求解思路如下
在这里插入图片描述
以模式串ababaa为例讲解其next数组求解过程
1.Next数组中Next[1]默认置0
在这里插入图片描述

2.第二个字符为b,其前面的字符串为a,字符串a不存在前缀和后缀,最长相等前后缀为0,所以Next[1]=最长相等前后缀(0)+1=1
在这里插入图片描述
3.第三个字符为a,前面的字符串为ab,字符串ab最长相等前后缀为0,所以Next[3]=最长相等前后缀(0)+1=1
在这里插入图片描述
4.第四个字符为a,其前面的字符串为aba,字符串aba最长相等前后缀为1(a,a),所以Next[4]=最长相等前后缀(1)+1=2

在这里插入图片描述
5.第五个字符为a,其前面的字符串为abab,字符串abab最长相等前后缀为2(ab,ab),所以Next[5]=最长相等前后缀(2)+1=3
在这里插入图片描述
6.第六个字符为a,其前面的字符串为ababa,字符串ababa最长相等前后缀为3(aba,aba),所以Next[6]=最长相等前后缀(3)+1=4
在这里插入图片描述
7.得到最终结果
在这里插入图片描述

4.Nextval数组求解
求解方法:
在这里插入图片描述
以模式串ababaa为例讲解其Nextval数组求解过程
1.Nextval数组中Nextval[1]默认置0
在这里插入图片描述
2.Nextval数组中的第二个字符是b,其对应的next数组值为next[2]=1,对比字符b与模式串的第一个字符a,b与a不是同一个字符,所以Nextval[2]=Next[2]=1
在这里插入图片描述
3.Nextval数组中的第三个字符是a,其对应的next数组值为next[3]=1,对比字符a与模式串的第一个字符a,a与a是同一个字符,所以Nextval[3]=Nextva[1]=0
在这里插入图片描述
4.Nextval数组中的第四个字符是b,其对应的next数组值为next[4]=2,对比字符b与模式串的第二个字符b,b与b是同一个字符,所以Nextval[4]=Nextva[2]=1
在这里插入图片描述
5.Nextval数组中的第五个字符是a,其对应的next数组值为next[5]=3,对比字符b与模式串的第三个字符a,a与a是同一个字符,所以Nextval[5]=Nextva[5]=0
在这里插入图片描述
6.Nextval数组中的第六个字符是a,其对应的next数组值为next[6]=4,对比字符a与模式串的第四个字符b,a与b不是同一个字符,所以Nextval[6]=Next[6]=4
在这里插入图片描述
5.举例
在这里插入图片描述
6.习题练习与讲解
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 14
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值