数据结构-KMP算法详解

本文详细解析了KMP算法的工作原理,通过构造查询表next[0,m)来避免匹配过程中的无效比较,减少文本串指针i的回溯,从而提高字符串匹配的效率。KMP算法的核心在于确定模式串在失配后的下一个匹配起点,保证文本串指针不回溯,通过寻找模式串中的最大相同真前缀和真后缀长度来构建next数组。" 105492986,5246597,Vue使用localStorage+sessionStorage实现登录状态管理,"['前端开发', 'Vue', 'JWT', '状态管理']
摘要由CSDN通过智能技术生成

设文本串为T[],欲匹配模式串为P[],文本串长度为n,模式串长度为m,则匹配过程中一次失配情况如下:
在这里插入图片描述
此时原文本串T[]可以划分为四个部分:已匹配子串的前缀、已匹配子串、失配字符X和失配字符的后缀子串。同理模式串P[]可划分为前缀、失配字符Y和后缀三部分。KMP算法的核心就在于如何在模式串的前缀中找到合适的字符作为下一次匹配过程的新起点,而不是简单的从模式串的起始位置重新开始匹配,从而减少匹配次数,提高效率。

构造查询表next[0,m)

为确定模式串下一次匹配过程的新起点,可以事先构造查询表next[0,m),在任意位置P[j]处失败后,将j替换为next[j],与文本串刚才失配的字符继续进行比较。
在这里插入图片描述
如上图所示,选择出新的位置t的条件是,模式串中新的前缀P[0,t)与文本串中原匹配子串的后缀P[j-t,j)相等,即满足P[0,t)==P[j-t,j),也就是说,已匹配的子串P[0,j)中存在相等的前缀和后缀。可以看到,对于任意的j,t的选取仅取决于模式串,与文本串无关。
对任意j,考察集合:
在这里插入图片描述
则在匹配过程中,一旦T[i]!=P[j],可从N(P,j)中选取某个t,令P[t]对准T[i],并继续比对,整个过程中,文本串的指针i始终不回溯。为保证安全,KMP算法在选取t的过程中选取集合N(P,j)中最大的t,因为此时若选择更小的t,可能会导致某些子串漏配。
对于集合N(P,j),若j>0,则至少可以取t=0,即已匹配子串P[0,j)仅有一个相同的前缀和后缀——空串,若j=0,即在模式串的起始位置发生了失配,特殊地令j=-1,在主算法中令原文本串的指针i增1,继续开始匹配,也就是说next[0]=-1。这里的特殊之处在于一般情况发生失配后需先调整j=next[j],然后判断T[i]与P[j]是否相同,再根据结果决定是否增加i。而取j=-1后则直接增加i,从头开始比较。
综上,对于next[j],即是在P[0,j)中,最大相同的真前缀和真后缀的长度。故有next[j+1]<=next[j]+1,即后一项的最大相同的真前缀和真后缀的长度不大于前一项的最大相同的真前缀和真后缀的长度加1,这一点用反证法可以证明。特别地,当且仅当P[j]==P[next[j]]时等号成立,即若当前项的next数组

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值