KMP算法Next数组求解

相信对于KMP算法本身大家都理解,最难理解的就是这个next数组的求解了。

这是代码

/* P 为模式串,下标从 0 开始 */
void GetNext(string P, int next[])
{
    int p_len = P.size();
    int i = 0;   // P 的下标
    int j = -1;  
    next[0] = -1;

    while (i < p_len)
    {
        if (j == -1 || P[i] == P[j])
        {
            i++;
            j++;
            next[i] = j;
        }
        else
            j = next[j];
    }
}

根据我的理解,i 和 j 可以看成是两个指针,用来跟踪当前匹配的位置。

可以发现 i 是会不断的往前推进的,顶多就是动,而 j 有时候是需要往后退的,那什么时候往前,什么时候后退,一次退多少是要确定的。

(1)j 前进的条件:

                  如果P[i] == P[j] 的时候,说明可能匹配到了一个前缀,这个时候得看看前缀会不会更长,所以 i 和 j都忘前推进。并且当P[i] == P[j]时,next[i] 的值是等于j的,为什么呢?可以理解为 j 是最长前缀,假如说刚好匹配了一个了,按理说j不应该要等于1 吗,为什么j还是等于0呢,是因为当目标字符串和源字符串发生失配的时候,要将失配的哪一位换成目标字符串的另外一位开头来匹配,对应为数组的下标,所以需要-1.

(2)j 后退是为什么?

                   P[i] != P[j] 的时候。其实在还没有匹配到相等的时候,j 的值是一直在-1 和 0 之间 取值的,当P[i] != P[j]的时候,j=next[j] 结果是-1 ,然后下一次循环由于j=-1 ,j++, j又等于0了,在这个过程中i 是不断的往后的。

                    加入在之前匹配到了几个前缀了,比如j=3 next[3]=2; 当再次P[i] != P[j]的时候,j=next[3]=2。

这是我的一点点总结,如果有什么决定不对的话,欢迎指正!

猜你喜欢

转载自blog.csdn.net/vfi7018/article/details/81072552