KMP算法

  参考博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html

  KMP算法用来匹配两个字符串,即b串是否为a的子串。

  普通算法的复杂度为O(n*m),KMP算法的复杂度为O(n+m)。

  用 i 计数 a 串的位置,用 j 计数 b 串的位置。

  普通算法:

  如果 a[i] != b[j] ,则 i 回溯,j=0。

  KMP算法:

  KMP算法和普通算法的区别在于,KMP消除的 i 的回溯,只需确定下次匹配 j 的位置即可。在KMP算法中引入了next数组,为了确定匹配不成功时,下次匹配时 j 的位置。next[j]的值表示P[0...j-1]中最长后缀的长度等于相同字符序列的前缀。

  对于next[]数组的定义如下:

  1) next[j] = -1  j = 0

  2) next[j] = max(k): 0<k<j   P[0...k-1]=P[j-k,j-1]

  3) next[j] = 0  其他

 如:

 P      a    b   a    b   a

 j      0    1   2    3   4

 next    -1   0   0    1   2

 即next[j]=k>0时,表示P[0...k-1]=P[j-k,j-1]

  KMP算法的思想就是:在匹配过程称,若发生不匹配的情况,如果next[j]>=0,则目标串的指针i不变,将模式串的指针j移动到next[j]的位置继续进行匹配;若next[j]=-1,则将i右移1位,并将j置0,继续进行比较。

int KMPMatch(char *s,char *p)
{
    int next[100];
    int i,j;
    i=0;
    j=0;
    getNext(p,next);
    while(i<strlen(s))
    {
        if(j==-1||s[i]==p[j])
        {
            i++;
            j++;
        }
        else
        {
            j=next[j];       //消除了指针i的回溯
        }
        if(j==strlen(p))
            return i-strlen(p);
    }
    return -1;
}

 求next数组

void getNext(char *p,int *next)
{
    int j,k;
    next[0]=-1;
    j=0;
    k=-1;
    while(j<strlen(p)-1)
    {
        if(k==-1||p[j]==p[k])    //匹配的情况下,p[j]==p[k]
        {
            j++;
            k++;
            next[j]=k;
        }
        else                   //p[j]!=p[k]
            k=next[k];
    }
}

 

posted @ 2013-08-03 15:17  yongren1zu  阅读(173)  评论(0编辑  收藏  举报