KMP算法-严蔚敏数据结构

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

算法具体实现以及相关说明建议直接B站搜索-严蔚敏数据结构。讲解详细,通俗易懂。

获得Next[]数组对应值的函数:

需注意的是,Next数组的第一个元素用来存长度,第二个元素往后才用来存数据,这样是更方便理解,因为此时的数据是从1开始。

1. 当模式串Q第j个字符和主串S第i个字符不等时存在等式:

Q1.....Qj-1 = Si-j+1 .. Si-1;

2.假设存在k,将模式串进行移位,移到第k位后。主串不动。

主串与移位后的模式串得出的等式:

(1)Q1 ... Qk-1 = Si-k+1 ..Si-1;

主串和未移位的模式串得出的等式:

(2)Qj-k+1 .... Qj-1 =Si-k+1 ..Si-1;(该等式就相当于1等式的子等式)

(1)和(2)等式就可以得出:

Qj-k+1 ... Qj-1 = Q1....Qk-1;那么只需要Qj-k+1...Qj-1 = Q1....Qk-1等式成立即可。

那么相关Next数组的数值我们就可以看出来了

eg:

               1 2 3 4 5 6 7 8

模式串: a b a a b c a c

Next[] :    0 1 1 2 2 3 1 2

但是当数据长度越长,越往后对其Next数组的数值的判断越复杂。

此时需要注意:当Next[i] = k,此时对Q[i]和Q[k]进行判断如果相等:Next[i+1]=k+1;

(Next[i] = k 说明 Qi-k+1 ... Qi-1 = Q1 .... Qk-1,那么当Qi=Qk所以就会存在

Qi-k+ ... Qi-1 Qi=Q1... Qk-1 Qk,那么Next[i+1] = k+1。)

如果不相等k=Next[k];

(当前模式串的Q[i] 不等于Q[k],我们将Qi的串看成主串,Qk的串看成模式串就很好理解了,.就拿上面举的例子来说 第4个字符的Next[4] = 2 ,且Q[4] 不等于Q[2]。我们将原有的模式串看成主串,将Q1 .. Q2 看成模式串T,因为T[2]和Q4不相等,那么我们就需要移位,移位多少就根据此时T[2]的Next[2]是多少。此时T[2]的Next[2]是1,那么就是Q[4]和T[1]继续判断,此时相等,那么k=2.如果不等,此时Next[1]=0,那么就从1重新开始比。)

总的来说就是如果Q[i]和Q[k]不相等,就将原有的看成主串,k长度的串看成字串,因为此时出现了不匹配的状况,所以需要移位,拿当前不匹配的当前位的Next值又是多少,就将k长度看成主串,其Next[k]长度看成字串,直达出现相等的时候或者Next = 0的时候。

此处用的就是递归的思想。

具体的例子可以去看严蔚敏老师的数据结构,里面有很详细的例子。

KMP算法改进:

            1 2 3 4 5

当主串 a a a b a 

模式串 a a a a c

此时模式串的Next值 分别是:

模式串:a a a a c

Next[]  :  0 1 2 3 4

当S[4] != T[4]时,i指针不动,j指针移到第3个字符。在进行S[4]与T[3]的比较,又不等,i指针不动,j指针移到第二个字符。此时可以看出多出来许多不必要的比较。

对Next数组的值求解进行改进:

 

 

新增的判断其主要部分在于如果T[j] =T[k]了就将nextval[j] =  nextval[k];因为T[j] = T[k],

当S[i] != T[j]时,j指针移到到nextval[j]位,但此时T[j] 与T[nextval[j]]是相等的,

那么S[i]与T[nextval[j]]必然是不相等的,那么还需要在进行一次移位。所以就进行了不必要的重复。新增的判断让其在相等的时候,就回溯到nextval[k]的位置,避免了重复的步骤。

因为我们这是从第一位字符开始的,那么回溯一次即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值