KMP算法重温

来源:互联网 发布:淘宝新手装修教程 编辑:程序博客网 时间:2024/04/29 12:51

        KMP就是字符串匹配算法,最朴素的字符串匹配算法,就是逐位匹配,不匹配就右移一位,这种方法效率太低。为了节省时间,利用已经匹配过的部分字符串的信息来为后续的匹配提供条件,减少匹配次数。

        KMP算法的关键就是获取next值,next[ j ] 是通过模式串得来的,关于next[ j ] 的算法也有普通和改进的,

        普通的获取next[ j ]的算法思想是:

               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  其他

      利用得到的next[]函数,进行KMP匹配,其思想就是:

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

     上面就是KMP算法的两个关键点。然而关于求next[ ]值,又有多种不同的方法,产生不同方法的原因是,改进朴素的方法,使匹配的结果更准确,效率更高。常用的求next[]的方法有递推式和直接求解式。

      递推的思想:

     根据定义next[0]=-1,假设next[j]=k, 即P[0...k-1]==P[j-k,j-1]

       1)若P[j]==P[k],则有P[0..k]==P[j-k,j],很显然,next[j+1]=next[j]+1=k+1;

       2)若P[j]!=P[k],则可以把其看做模式匹配的问题,即匹配失败的时候,k值如何移动,显然k=next[k]。

代码:

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];
    }
}