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