KMP之nextval推导

本文深入解析了KMP字符串匹配算法的原理,通过分析子串的前缀与后缀特性,介绍了如何利用这些特性来优化匹配过程。同时,还探讨了next和nextval数组的构建方法及其在实际匹配中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

KMP字符串匹配算法的本质呢就是分析子串自身的特点来优化算法。

第一个特点 前缀与后缀

来自《算法导论》的一个实例
这里写图片描述
图a
文本 T , 与子串 P,已经匹配成功的q=5个字符,现在第六个字符匹配失败,要将子串P向前移动即 s 变大。s+1 的移动 显然失败,s+2的移动如下
这里写图片描述
图b
能成功匹配到k=3个字符,现在分析这两次匹配到的内容
这里写图片描述
图c
可以看出Pk 与 Pq的后三个字符相匹配, 而Pk其实就是Pq的前三个字符,
换句话说就是 Pq的 前三个字符与后三个字符相同。
‘aba’既是Pq的前缀也是Pq的后缀, 符合这种特征的还有’a’ 其中’aba’是最长的
我们用π[q]来表示Pq中前缀与后缀相同的最长长度
π称之为前缀函数
完整的P的前缀函数如下

i1234567
P[i]ababaca
π0012301

使用这个函数我们可以得到KMP算法中的重要数组next
next数组的意义为:为当第子串中i个字符匹配失败时,要从子串的第next[i]个字符继续比较。
分析上一个例子

  • 在第 6 个字符第一次匹配失败 i= 6
  • 我们现在知道 P 的第 5 个字符的 π[i1] = 3
  • 所以我们应该向前移动 qπ[i1] = 2 个字符
  • 即与第 π[i1]+1=3 比较

next[n]={0,π[n1]+1,n=1n>1
i1234567
P[i]ababaca
π0012301
next[i]0112341

第二个特点 nextval

如果用上例的P与下面一个文本匹配
T = a b a b c a a a..
p = a b a b a c a

  • 第5个字符匹配失’a’,按照next函数 应与第 next[5] = 3个字符比较
  • 发现p[3] = ‘a’ , 仍然失配,继续next[3] = 1
  • 再一次p[1] = ‘a’ 最终 next[1] = 0

上面的过程发现连续的’a’造成这几步无用的操作,其实这一点我们可以提前预见到并避免。

当我们在p[q] 上失配时我们下一个匹配的是 p[next[q]] , 如果出现上述情况即

p[ q ] == p[ next[ q ] ] 则匹配一定失败 所以会直接匹配 p[next[ next[q] ]]
于是我们制定一个新的数组nextval

nextval[n]=0,nextval[next[n]],next[n],n=0P[n]=P[next[n]]P[n]P[next[n]]
i1234567
P[i]ababaca
π0012301
next[i]0112341
nextval[i]0101040
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值