小记KMP算法

近日温习数据结构,至KMP算法,虽知特征函数next[j]生成步骤,奈何不明其算法,惑不已。一阵写写画画修修补补之后,方才补得如下代码,以备后查。

PS:KMP算法根据模式字符串P本身的性质,省略了P和目标字符串T进行比较时一些不可能匹配的步骤,提高了匹配的时间性能。

#include <stdio.h>
#include <stdlib.h>
#include<string.h>

//KMP算法得到next(j) 官方版
void getNext(char * p,int lengthP,int * next)
{
    int j=0,k=-1;
    next[0] = -1;
    while(j<lengthP)
    {
        if(k==-1||p[j]==p[k])
        {
            j++;
            k++;
            next[j]=k;
        }
        else k=next[k];
    }
}

//已知next(0)~next(j0),求next(j0+1),包含递归调用
//p:模式字符串P
//j0:表示已知next(0)~next(j0),求next(j0+1)
//j:该参数的传入值根据递归层次的不同而变化
//next:模式字符串的特征函数
//已知next(j0)=k+1,即P[j0-1-k] ... ... P[j0-1] = P[0] ... ... P[k]
//若P[j0]=P[k+1],则next(j0+1)=k+2;若p[j0]!=P[k+1],则必须求l使得P[k-l-1] ... ... P[k]=P[0] ... ... P[l]。
//若P[j0]=P[l+1]则next(j0+1)=l+2;若P[j0]!=P[l+1],则必须求m使得P[k-m-1] ... ...P[h]=P[0] ... ... P[m]
//以此类推下去,最后有两种情况,一是存在某个数n,满足了P[j0]=P[n+1],此时next(j0+1)=n+2;
//另一种情况是不存在这样一个数,迭代到最后只能让P[0]对应P[j0+1],即next(j0+1)=0
 int produceNext(char *p,int j0,int j,int *next)
 {
     if(0==j)return 0;
     int k=next[j]-1;
     if(p[j0]==p[k+1])return k+2;
     else return produceNext(p,j0,k+1,next);
 }
 //其实上面的递归函数纯属多此一举,按照上面的分析流程,用递推实现即可
 int produceNext2(char *p,int j0,int *next)
 {
     int k,j=j0;
     while(j>0)
     {
         k=next[j]-1;
         if(p[j0]==p[k+1])return k+2;
         else j=k+1;
     }
     return 0;
 }
//KMP算法得到next(j) 个人版
void recursiveGetNext(char *p,int lengthP,int * next)
{
  next[0]=-1;
  int j=1;
  for(;j<lengthP;++j)
  next[j]=produceNext2(p,j-1,next);
}

int main()
{
    char p[] = "aaaaaabbbbb";
    int lengthP = strlen(p);
    printf("String: %s\n",p);
    printf("Length:%d\n",lengthP);
    int * next = (int *)malloc(lengthP);

    printf("Official version:\n");
    getNext(p,lengthP,next);
    int i;
    for(i=0;i<lengthP;++i)
    {
        printf("%d ",next[i]);
        next[i]=0;
    }

    printf("\nPersonal version:\n");
    recursiveGetNext(p,lengthP,next);
    for(i=0;i<lengthP;++i)
    {
        printf("%d ",next[i]);
    }
    free(next);

    return 0;
}

 

posted @ 2012-03-18 00:47  iliveido  Views(192)  Comments(0)    收藏  举报