kmp理解篇

来源:互联网 发布:快递业务考试软件 编辑:程序博客网 时间:2024/06/07 15:13

kmp的自我理解篇
kmp算法又称看毛片算法,是一种高效的字符串匹配算法,主要对重复的匹配量有很大的优化作用,主要用于关键串对主串的匹配。
算法一般分两步:
一是关键串p的自己匹配得到跳转序列,即匹配失败时候可跳转序列,通过跳转序列去除重复匹配的位置,来达到线性的时间;
二是利用一得到的跳转序列进行关键串p和主串t的匹配,原则就是能匹配就向前推进,不能匹配就跳转,最终跳到主串开始。
跳转数组求解:

void makeNext(const char P[],int next[]){    int q,k;                //q:模版字符串下标;k:最大前后缀长度    int m = strlen(P);          //模版字符串长度    next[0] = 0;            //模版字符串的第一个字符的最大前后缀长度为0    for (q = 1,k = 0; q < m; ++q)   //for循环,从第二个字符开始,依次计算每一个字符对应的next值    {        while(k > 0 && P[q] != P[k])    //递归的求出P[0]···P[q]的最大的相同的前后缀长度k            k = next[k-1];      //不理解没关系看下面的分析,这个while循环是整段代码的精髓所在,确实不好理解          if (P[q] == P[k])       //如果相等,那么最大相同前后缀长度加1        {            k++;        }        next[q] = k;    }}

kmp举例:

#include<stdio.h>#include<string.h>void makeNext(const char P[],int next[]){    int q,k;    int m = strlen(P);    next[0] = 0;    for (q = 1,k = 0; q < m; ++q)    {        while(k > 0 && P[q] != P[k])            k = next[k-1];        if (P[q] == P[k])        {            k++;        }        next[q] = k;    }}int kmp(const char T[],const char P[],int next[]){    int n,m;    int i,q;    n = strlen(T);    m = strlen(P);    makeNext(P,next);    for (i = 0,q = 0; i < n; ++i)    {        while(q > 0 && P[q] != T[i])            q = next[q-1];        if (P[q] == T[i])        {            q++;        }        if (q == m)        {            printf("Pattern occurs with shift:%d\n",(i-m+1));        }    }    }int main(){    int i;    int next[20]={0};    char T[] = "ababxbababcadfdsss";    char P[] = "abcdabd";    printf("%s\n",T);    printf("%s\n",P );    // makeNext(P,next);    kmp(T,P,next);    for (i = 0; i < strlen(P); ++i)    {        printf("%d ",next[i]);    }    printf("\n");    return 0;}

网上的模版求next的数组大致类似,细节上如第一位的赋值不同,需要注意。
另有功能更强大的扩展kmp;

原创粉丝点击