全网最详细的KMP算法详解

KMP算法

1、背景

KMP 算法是 D.E.Knuth、J,H,Morris 和 V.R.Pratt 三位神人共同提出的,称之为 Knuth-Morria-Pratt 算法,简称 KMP 算法。该算法相对于 Brute-Force(暴力)算法有比较大的改进,主要是消除了主串指针的回溯,从而使算法效率有了某种程度的提高。

2、求解next数组

按照搜索引擎方面的查找,似乎有两种计算模式。

模式串: ABCDABD

1、计算maxL数组

对于A,没有前后缀,所以 为0

对于AB,前缀为A,后缀为B,最大相同串长度为0

对于ABC,前缀为A,AB,后缀为C,BC,最大相同串长度为0

对于ABCD,前缀为A,AB,ABC,后缀为D,CD,BCD,最大相同串长度为0

对于ABCDA,前缀为A,AB,ABC,ABCD,后缀为A,DA,CDA,BCDA,最大相同串 A 长度为1

对于ABCDAB,前缀为A,AB,ABC,ABCD,ABCDA,后缀为B,AB,DAB,CDAB,BCDAB,最大相同串 AB 长度为2

对于ABCDABD,前缀为A,AB,ABC,ABCD,ABCDA,ABCDAB,后缀为D,BD,ABD,DABD,CDABD,BCDABD,最大相同串 长度为0

所以可得

0 1 2 3 4 5 6
Str A B C D A B D
maxL 0 0 0 0 1 2 0

针对next数组与MaxL之间的关系

如果next[0]= 0, 则next[i] = maxL[i-1]+1

如果next[0]= -1, 则next[i] = maxL[i-1]

我们这边采取的是next[0]=0,可得

0 1 2 3 4 5 6
str A B C D A B D
maxL 0 0 0 0 1 2 0
next 0 1 1 1 1 2 3
2、直接求解next数组

计算规则:

当前下标为i,则查看 str[i-1] 与 str[next[i-1]-1]之间的值是否一致

如果一致,则 next[i] = next[i-1]+1

如果不一致,则 k=next[i-1]-1,

​ 比较str[i-1] 与 str[k],迭代K,知道两个值一致,则 next[i] = next[k] + 1

​ 如果比较到第一位都不相等,则next[i] = 1

如果直接求解next数组的话,则next[0]=0, next[1]=1是默认值,所以需要从2开始测算

0 1 2 3 4 5 6
str A B C D A B D
next 0 1

当前i=2, str[i-1] = ‘B’, next[i-1] = next[1] = 1, 所以对比 str[1] 与 str[0],发现不一致,同时已经比较到头部,所以next[2] = 1

0 1 2 3 4 5 6
str A B C D A B D
next 0 1 1

当前i=3, str[i-1] = ‘C’, next[i-1] = next[2] = 1, 所以对比 str[2] 与 str[0],发现不一致,同时已经比较到头部,所以next[3] = 1

0 1 2 3 4 5 6
str A B C D A B D
next 0 1 1 1

当前i=4, str[i-1] = ‘D’, next[i-1] = next[3] = 1, 所以对比 str[3] 与 str[0],发现不一致,同时已经比较到头部,所以next[4] = 1

0 1 2 3 4 5 6
str A B C D A B D
next 0 1 1 1 1

当前i=5, str[i-1] = ‘A’, next[i-1] = next[4] = 1, 所以对比 str[4] 与 str[0],发现一致,所以next[5] = next[4] + 1 = 2

0 1 2 3 4 5 6
str A B C D A B D
next 0 1 1 1 1 2

当前i=6, str[i-1] = ‘B’, next[i-1] = next[5] = 1, 所以对比 str[5] 与 str[0],发现一致,所以next[6] = next[5] + 1 =3

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值