KMP算法(模板)
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;
}