KMP算法

关于KMP算法个人理解

笔者经过一个下午的整理,基本走通了所有逻辑。至于代码就不贴上了,功底有点烂。思路通了大于一切 代码怎么都能挤出来的

有如下一组字符串

A:abcdabcxabcd 

B:abcxabcd

需要做的事 就是在A中寻找有没有B字符串

第一个要理解的点,B字符串需要首先自我匹配是否有相同的前缀后缀

                     B: a  b  c  x  a  b  c  d

                          0  1  2  3  4  5  6  7

构建next数组   0  0  0  0  1  2  3  0  

关于这个next数组怎么得来,有变量 i  j ,i代表B数组下标0,j代表B数组1(从1开始)进行匹配

index[0] = 0,这是初始值

取i=0 对应的字符串 a 与j=1对应的字符串b 比较,此时不相同 j++,数组next赋值 index[1] = 0;

取i=0 对应的字符串 a 与j=2对应的字符串c 比较,此时不相同 j++,数组next赋值 index[2] = 0;

取i=0 对应的字符串 a 与j=3对应的字符串x 比较,此时不相同 j++,数组next赋值 index[3] = 0;

取i=0 对应的字符串 a 与j=4对应的字符串a 比较,此时结果相同,则i++,且j++,并且next赋值index[4] = 1 ,意思是相同的话就+1;

(注释:这里是,相同的情况,会写入i+1的值,此时i = 0  所以+1 )

取i=1 对应的字符串 b 与 j = 5对应的字符串b比较,此时结果相同,,则i++,且j++,并且next赋值index[5] = 2 ,意思是相同的话就+1;

(注释:这里是,相同的情况,会写入i+1的值,此时i = 1 所以+1 )

取i=2 对应的字符串 c 与 j = 6对应的字符串c比较,此时结果相同,,则i++,且j++,并且next赋值index[6] = 3 ,意思是相同的话就+1;

(注释:这里是,相同的情况,会写入i+1的值,此时i = 2 所以+1 )

特殊情况来了

取i = 3对应的字符串x 与 j =7对应的字符串d比较,此时结果不同,那么i取前面(i--)取2对应的字符串c还是不同,再取

i-- 取1不同 会发现没有相同的,此时整个组没有与d相同的字符串,则赋值i=0并且填入index[7] = 0;

和上面一样的数组,有点太长了 所以直接拿下来

                     B: a  b  c  x  a  b  c  d

                          0  1  2  3  4  5  6  7

构建next数组   0  0  0  0  1  2  3  0  

拿到了3 意思就是这个数组最大的相同前缀是123 对应的也就是abc

再回到我们的字符串来

A:a    b    c    d    a    b    c    x    a    b    c    f      a          b          c    x    a        b        c        x        a        b        c        d                  i

       0    1    2    3    4    5    6    7    8    9  10  11  12        13       14  15  16      17      18      19   20      21     22        23

B:a    b    c    x    a    b    c    d            j            (next: 0  0  0  0  1  2  3  0  )

       0    1    2    3    4    5    6    7

进行第一次匹配 会发现在i=3并且j=3的时候字符串不匹配 触发重新匹配方法

此时查询在next的数组下标-1里面对应的值为0,所以j 又回到0 并且i从i+1 从i=4开始匹配

第二次匹配开始,i = 4 i = 5 i = 6 i =7 ......一直到 i = 11不匹配,

此时j = 7 -1 查到对应的值为next【index】 = 3 ,所以可以肯定的是,3前面的字符串肯定都包含 所以只需要在b里面的next =3 开始查找就Ok

此时 需要匹配的值为next下标为3的值为x 取出来 x与 i = 11比较,为f 还是不匹配(这样就避免回到b字符串的头部了,)

但是这里还是不匹配,此时取next-1的值 为0 又开始从0开始(回到子串的头部,因为被F打断了)

开始第三次匹配,此时一直到 i = 18 并且 j =7 出现不匹配情况,此时J-1=6 取c 与 i =18 比较,是C,则直接继续往下开始匹配x a b cd 

最后这种情况是因为取出来的值和相对应的比较的值相等 所以才继续匹配(因为取出来的值是有相同前缀的,i = 18的c 前面是肯定包含了abc的)此时对应的next数组值为3,直接开始从B字符串的下标为3的值X开始匹配,与i = 19匹配 是匹配的话就继续匹配 不匹配 则从0开始。

好了kmp的算法和规则到此结束。(避免了会从B字符串从头开始,一旦碰到相同前缀的时候)

你可能感兴趣的:(KMP算法)