在数据结构与算法课程中,串的匹配中,时间和空间消耗最大的是BF蛮力法。
基于BF蛮力法的低效率,KMP算法减少了不必要的无效匹配。算法中的核心是要对子串计算next值
下面先来看下公式的定义:
这个公式比较抽象,我们用这个公式来看看教材上的一个子串的计算过程。
j | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
模式串 | a | b | c | a | a | b | a | b | c |
next值 | 0 | 1 | 1 | 1 | 2 | 2 | 3 | 2 | 3 |
获得步骤 | 计算1 | 计算2 | 计算3 | 计算4 | 计算5 | 计算6 | 计算7 | 计算8 | 计算9 |
计算1:next[1]=a 因为 j=1 ,直接对应公式第一项,next=0
计算2:next[2]=b j=2;对应公式第二项 1<=k<2 ;当k=1时,公式为 但 。使用第三项 next=1
计算3:next[3]=c j=3;对应公式第二项;k=1/2 ;k=1没有意义,下面不再判断
当k=2时,公式为 但 使用第三项next=1
计算4:next[4]=a j=4;对应公式第二项 ,k=2/3。
当K=2时,判断公式 但
当k=3时,判断公式 但 两个K值都不满足,使用第三项 next=1
计算5:next[5]=a j=5;对应公式第二项 ,k=2/3/4。
当K=2时,判断公式
当k=3时,判断公式
当K=4时,判断公式 k=2可用,next=2
计算6:next[6]=b j=6 ;对应公式第二项 ,k=2/3/4/5
当K=2时,判断公式
当k=3时,判断公式
当K=4时,判断公式
当K=5时,判断公式 k=2可用,next=2
计算7:next[7]=a j=7 ;对应公式第二项 ,k=2/3/4/5/6
当K=2时,判断公式
当k=3时,判断公式
当K=4时,判断公式
当K=5时,判断公式 k=3可用,next=3
按照公式来计算,看出来非常的繁琐,有没有简单的计算方法呢?仔细看计算1-7中的比对步骤,可以得到下面的直观步骤。
计算字符位置为n的字符的index值,看前面有n-1个字符,需要判断n-2次。
将位置n字符前面的子串,分为从第一个字符开始命名为A 和 从n-1位置往前命名为B,
判断分别是 A1 vs B1,A2 vs B2 ......... An-2 vs Bn-2,如果相等,取第几次的值+1,就是字符的next值。
下面用这个方法来计算后面两个字符:
计算8:next[8]=b,前面有7个字符,需要比较6次:
A1 vs B1:[1] vs [7] a=a A1 vs B1 可用,next=1+1=2
A2 vs B2:[1][2] vs [6][7] ab <>ba
A3 vs B3:[1][2][3] vs [5][6][7] abc <>aba
A4 vs B4:[1][2][3][4] vs [4][5][6][7] abca <>aaba
A5 vs B5:[1][2][3][4][5] vs [3][4][5][6][7] abcaa <>caaba
A6 vs B6:[1][2][3][4][5][6] vs [2][3][4][5][6][7] abcaab <>bcaaba
计算9:快速计算,只有 A2 vs B2 ab=ab ,next=2+1=3
这样基本可以在1-2分钟之内,快速的写出字符串的next值。