由于KMP算法比较难,所以建议初学者分两个阶段学习。
第一个阶段先理解算法思想,可以参考这篇文章:点击打开链接
第二个阶段,理解算法的具体实现,本文主要讲解这部分,需要注意的地方都在程序里了,自己看吧
程序(调试通过):
#include <stdio.h> #include <string.h> int KMP(char* s, char* pattern, int start, int next[]); void get_new_next(char* pattern, int next[]); int main() { int n; char* s= "lakgjkaglamdaltjie"; char* pattern= "lamd"; int next[5]; //长度为strlen(pattern)+1 int start = 0; //从start处开始搜索字符串s get_new_next(pattern, next); n = KMP(s, pattern, start, next); printf("%d\n",n); return 0; } //返回pattern在字符串s中匹配的第一个位置,例如:本例返回3 int KMP(char* s, char* pattern, int start, int next[]) { int i = start, j = 1; while (i<=(int)strlen(s) && j<=(int)strlen(pattern)) { if(j==0 || s[i]==pattern[j-1]) //找到第一个匹配的字符,然后每次移动1位继续匹配 { i++; j++; } else j = next[j]; //匹配失败,则查找部分匹配表,移动若干位 } if(j>(int)strlen(pattern)) return i-strlen(pattern)+1; else return -1; //Not found } //优化后的get_new_next函数(构造next[]的部分匹配表) void get_new_next(char* pattern, int next[]) { int k=-1,j=0; next[0]=-1; while (pattern[j]!='\0') //循环直到pattern遇到结束符 { //如果j的前面k个字符与开头的k个字符不相等 while(k!=-1 && pattern[k]!=pattern[j]) k = next[k]; j++; k++; //如果j的前面k个字符与开头的k个字符相等 if(pattern[k] == pattern[j]) next[j] = next[k]; else next[j] = k; //pattern[k]!=pattern[j](1<=k<j) } }
时间: 2024-12-21 04:48:22