KMP算法用于字符串匹配,有两个字符串s,p,一个是文本串s,另一个是模式串p,现在要查找模式串p在文本串s中首次出现的位置是多少。暴力匹配的算法很容易想到,但是时间复杂度太高,运用KMP算法可以很好地解决这个问题。
算法详解 从头到尾彻底理解KMP
//得到模式串p的next数组 void getnext(char *p,int *next){ int lenp=strlen(p); next[0]=-1; int k=-1,j=0; while(j+1<lenp){ if(-1==k || p[k]==p[j]){ ++j; ++k; next[j]=k; } else k=next[k]; } } //返回模式串p在文本串s中第一次出现的位置(从0下标开始),匹配失败则返回-1 int kmp(char *s,char *p,int *next){ int lens=strlen(s); int lenp=strlen(p); int i=0,j=0; while(i<lens && j<lenp){ if(-1==j || s[i]==p[j]){ ++i; ++j; } else j=next[j]; } return j==lenp?i-j+1:-1; }
模板题 hdu 1711 稍有区别的是这道题不是字符串的匹配,而是整数序列的匹配,但思路和KMP算法是完全一样的
#include<cstdio> using namespace std; const int maxs=1000050; const int maxp=10050; int lens,lenp; int s[maxs],p[maxp]; int next[maxp]; void getnext(){ next[0]=-1; int k=-1,j=0; while(j+1<lenp){ if(-1==k || p[k]==p[j]){ ++j; ++k; next[j]=k; } else k=next[k]; } } int kmp(){ int i=0,j=0; while(i<lens && j<lenp){ if(-1==j || s[i]==p[j]){ ++i; ++j; } else j=next[j]; } return j==lenp?i-j+1:-1; } int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d%d",&lens,&lenp); for(int i=0;i<lens;++i) scanf("%d",&s[i]); for(int i=0;i<lenp;++i) scanf("%d",&p[i]); getnext(); int ans=kmp(); printf("%d\n",ans); } return 0; }
来源:https://www.cnblogs.com/wafish/p/10465326.html