数据结构与算法~串的模式匹配~KMP匹配算法中next的快速计算法

在数据结构与算法课程中,串的匹配中,时间和空间消耗最大的是BF蛮力法。

基于BF蛮力法的低效率,KMP算法减少了不必要的无效匹配。算法中的核心是要对子串计算next值

下面先来看下公式的定义:

next[j]=\begin{cases} & \0, \j= 1 & \max{k} | 1\leqslant k < j \ and \ \ p_{1}...p_{k-1}=p_{j-k+1}...p_{j-1}} \\ & \1, \j= not k; \end{cases}

 这个公式比较抽象,我们用这个公式来看看教材上的一个子串的计算过程。

模式串的index计算
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时,公式为 p_{1}=p_{2-1+1}  但  p_{1}\neq p_{2}使用第三项  next=1


计算3:next[3]=c   j=3;对应公式第二项1\leqslant k<3;k=1/2 ;k=1没有意义,下面不再判断

 当k=2时,公式为p_{1}=p_{3-2+1}    但 p_{1}\neq p_{2}    使用第三项next=1


计算4:next[4]=a   j=4;对应公式第二项  1\leqslant k<4 ,k=2/3。

 当K=2时,判断公式  p_{1}=p_{4-2+1}               但   p_{1}\neq p_{3}    

 当k=3时,判断公式  p_{1}p_{2}=p_{4-3+1}p_{4-1}   但   p_{1}p_{2}\neq p_{2}p_{3}         两个K值都不满足,使用第三项  next=1


计算5:next[5]=a j=5;对应公式第二项  1\leqslant k<5 ,k=2/3/4。

当K=2时,判断公式  p_{1}=p_{5-2+1}                                    p_{1}=p_{4}    

当k=3时,判断公式  p_{1}p_{2}=p_{5-3+1}p_{5-1}                       p_{1}p_{2}\neq p_{3}p_{4} 

当K=4时,判断公式  p_{1}p_{2}p_{3}=p_{5-4+1}p_{5-4+2}p_{5-1}     p_{1}p_{2}p_{3}\neq p_{2}p_{3}p_{4}      k=2可用,next=2


计算6:next[6]=b     j=6 ;对应公式第二项  1\leqslant k<6 ,k=2/3/4/5

当K=2时,判断公式  p_{1}=p_{6-2+1}                                    p_{1}=p_{5}    

当k=3时,判断公式  p_{1}p_{2}=p_{6-3+1}p_{6-1}                       p_{1}p_{2}\neq p_{4}p_{5} 

当K=4时,判断公式  p_{1}p_{2}p_{3}=p_{6-4+1}p_{6-4+2}p_{6-1}     p_{1}p_{2}p_{3}\neq p_{3}p_{4}p_{5}      

当K=5时,判断公式  p_{1}p_{2}p_{3}p_{4}=p_{6-5+1}p_{6-5+2}p_{6-5+3}p_{6-1}     p_{1}p_{2}p_{3}p_{4}\neq p_{2}p_{3}p_{4}p_{5}     k=2可用,next=2


计算7:next[7]=a     j=7 ;对应公式第二项  1\leqslant k<7 ,k=2/3/4/5/6

当K=2时,判断公式  p_{1}=p_{7-2+1}                                    p_{1}\neq p_{6}    

当k=3时,判断公式  p_{1}p_{2}=p_{7-3+1}p_{7-1}                       p_{1}p_{2}=p_{5}p_{6} 

当K=4时,判断公式  p_{1}p_{2}p_{3}=p_{7-4+1}p_{7-4+2}p_{7-1}     p_{1}p_{2}p_{3}\neq p_{4}p_{5}p_{6}      

当K=5时,判断公式  p_{1}p_{2}p_{3}p_{4}=p_{7-5+1}p_{7-5+2}p_{7-5+3}p_{7-1}     p_{1}p_{2}p_{3}p_{4}\neq p_{3}p_{4}p_{5}p_{6}     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值。

你可能感兴趣的:(数据结构与算法C语言,#,串,数据结构与算法,串,串的模式匹配,KMP,next)