KMP算法

KMP算法
在介绍KMP算法之前,先介绍一下BF算法。
一.BF算法
BF算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串P的第一个字符进行匹配,若相等,则继续比较S的第二个字符和P的第二个字符;若不相等,则比较S的第二个字符和P的第一个字符,依次比较下去,直到得出最后的匹配结果。
举例说明:
S:  ababcababa
P:  ababa
BF算法匹配的步骤如下
i=0                      i=1                   i=2                 i=3                 i=4
第一趟:ababcababa         第二趟:ababcababa      第三趟:ababcababa    第四趟:ababcababa    第五趟:ababcababa
ababa                    ababa                 ababa               ababa               ababa
j=0                      j=1                   j=2                 j=3                 j=4(i和j回溯)
i=1                      i=2                   i=3                 i=4                 i=3
第六趟:ababcababa         第七趟:ababcababa      第八趟:ababcababa    第九趟:ababcababa   第十趟:ababcababa
ababa                    ababa                 ababa               ababa               ababa
j=0                      j=0                   j=1                 j=2(i和j回溯)        j=0
i=4                      i=5                   i=6                 i=7                 i=8
第十一趟:ababcababa       第十二趟:ababcababa    第十三趟:ababcababa  第十四趟:ababcababa  第十五趟:ababcababa
ababa                    ababa                 ababa               ababa               ababa
j=0                      j=0                   j=1                 j=2                 j=3
i=9
第十六趟:ababcababa
ababa
j=4(匹配成功)
代码实现:

int BFMatch(char *s,char *p)
{
    int i,j;
    i=0;
    while(i<strlen(s))
    {
        j=0;
        while(s[i]==p[j]&&j<strlen(p))
        {
            i++;
            j++;
        }
        if(j==strlen(p))
            return i-strlen(p);
        i=i-j+1;                //指针i回溯
    }
    return -1;    
}

   其实在上面的匹配过程中,有很多比较是多余的。在第五趟匹配失败的时候,在第六趟,i可以保持不变,j值为2。因为在前面匹配的过程中,对于串S,已知s0s1s2s3=p0p1p2p3,又因为p0!=p1!,所以第六趟的匹配是多余的。又由于p0==p2,p1==p3,所以第七趟和第八趟的匹配也是多余的。在KMP算法中就省略了这些多余的匹配。
二.KMP算法
KMP算法之所以叫做KMP算法是因为这个算法是由三个人共同提出来的,就取三个人名字的首字母作为该算法的名字。其实KMP算法与BF算法的区别就在于KMP算法巧妙的消除了指针i的回溯问题,只需确定下次匹配j的位置即可,使得问题的复杂度由O(mn)下降到O(m+n)。
在KMP算法中,为了确定在匹配不成功时,下次匹配时j的位置,引入了next[]数组,next[j]的值表示P[0…j-1]中最长后缀的长度等于相同字符序列的前缀。
对于next[]数组的定义如下:
1) next[j] = -1  j = 0
2) next[j] = max(k): 0

发表评论?

1 条评论。

  1. 夫人威武~!如果您下次粘过来的时候能处理下标签、格式、转译、链接,顺便再加点自己的心得和补充神马的就更好了。

发表评论


请输入正确的验证码