kmp

来源:互联网 发布:遗传身高计算法 编辑:程序博客网 时间:2024/06/05 11:23

                       好长时间没写博了,这里写下自己对kmp的理解好了,小白之作。

               kmp算法又称看毛片算法,是一种高效的字符匹配算法,主要对重复的匹配量有很大的优化作用,其中关键在于next数组的求解;呃,这点网上好多的板子,这里摘录一个:

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;    }}
代码用循环写的大概就是每到一处向前查找相同的字符,其中注意next数组的运用,因为next是线性向后推近的,前面的不变,后面的多利用前面的有用信息;

           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的求解并类似,关键在while循环,不同就是匹配的不同,模版是自我匹配所以跟自己比较,题目的匹配就换成题目给的好了,具体用模版的时候可以再优化,比如要暴力的时候,next数组不变时候,就是用到的范围不一样,就在加个参数传,把其中的nm值改掉就好;

网上的模版求next的数组大致类似,细节上如第一位的赋值不同,需要注意。




0 0
原创粉丝点击