KMP算法

作者: 山上的神仙 | 来源:发表于2018-12-31 17:16 被阅读0次

    关于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算法

          本文链接:https://www.haomeiwen.com/subject/ohqwlqtx.html