关于KMP算法的NEXT数组解释

模式串中所有“以第i位结尾的子串(后缀子串”显然共i个,不过我们要排除掉最长的一个即P[1~ i],剩下一共i-1个即:

子串长度
P[i]
1
P[i-1~  i]
2
P[i-1~  i]
3
...

P[3 ~ i] 
i-2
P[3 ~ i] 
i-1



模式串中所有“长度不超过i的前缀(前缀子串”显然共i个,不过我们要排除掉最长的一个即P[1~ i],剩下一共i-1个即:

子串长度
P[1]
1
P[1 ~ 2] 
2
P[1 ~ 3]
3
...

P[1 ~ i-2]
i-2
P[1 ~ i-1]
i-1


上面我们分别得到了关于下标i的一组“后缀”和一组“前缀

然后我们用每一个“后缀子串”和对应相同长度的“前缀子串”进行匹配,即考虑下面所有的“子串对”:

后缀子串A前缀子串B长度
P[i]
P[1] 
1
P[i-1 ~ i]
P[1 ~ 2] 
2
P[i-2 ~ i]
P[1 ~ 3]
3
...
 
P[3 ~ i]
P[1 ~ i-2]
i-2
P[2 ~ i]
P[1 ~ i-1] 
i-1


运气好的话总有一对或多对“后缀”和“前缀”完全相等

那么NEXT[i]就代表最长的一对“后缀=前缀”的长度

如果很不幸没有一对相等的后缀和前缀,那么NEXT[i] = 0


*例:

i =1234567
P[i] = abababc
NEXT[i] =0012340


换一种说法,比如上例中NEXT[5]的值是3,代表:

如果模式串前5位都与目标匹配,但下一位(6号位)发生了失配,那么就右移整个模式串!

移动多少呢?也就是把3移动到5的位置!

想象模式串abababc是一张小纸条,那么用你的大手按住3号位的a,向右拖到5号位,连同整张小纸条一起!

为什么可以这样移?因为模式串的123位345位一样(都是aba,长度是3)


再换一种说法,比如上例中NEXT[5]的值是3,代表:

如果模式串前5位都与目标匹配,但下一位(6号位)发生了失配,就像

T:ababaccccccccabababca

P:abababc

此时如果是Brute-Force的话,则需要右移模式串1位,然后T和P的指针都返回起点,重头开始比较……

但如果是KMP的话,T的指针不需要变,还是指向第6位(即失配的那一位)

而只要把模式串p右移一下,让绿色的两个aba对齐,继续比对T的第6位


--- 


这样一来,在整个KMP的过程中,目标串T的指针从没有发生回溯,始终向右走。

由于T的指针绝不会回头,并且任何一对T[i]与P[j]最多只比较一次(就算是Brute-Force也是最多只比一次)

所以算法的复杂度奇妙的被锁定到了O(N+M)


copyright by

scarlet.MP5

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值