由于在处理每次成功的时候让i=i-len2+1,相当于回溯了,后来一想,本次成功,相当于“失败”,i不动,
j需要用哪里来匹配?当然是next{j}!嘛(此处j=len2)。第一次真正敲kmp,完全根据自己理解敲出来的总控。
#include<iostream> //用string 220ms,char *,scanf 110ms #include<string> #include<cstdio> #include<cstring> using namespace std; int next[40000]; void get_next(char * s) //next[len]也求得了(有意义)。 { int i=0,j=-1; next[0]=-1; int len=strlen(s); while(i<len) { if(j==-1||s[i]==s[j]) { i++;j++; if(s[i]==s[j]) //此处只为文本的匹配,可以加快! next[i]=next[j]; else next[i]=j; } else { j=next[j]; } } } int count=0; void kmp(char * tx,char * w) { int i=-1,j=-1; //为了下面++ int len2=strlen(w); int len1=strlen(tx); while(i<len1) { if(j==-1||tx[i]==w[j]) { i++;j++; } else { j=next[j]; } if(j==len2) //一次匹配成功, { count++; j=next[j]; //j对应位置。 } } } char tx[1000008];char w[10010]; int main() { int ta; cin>>ta; while(ta--) { count=0; scanf("%s ",w); scanf("%s",tx); get_next(w); kmp(tx,w); printf("%d ",count); } return 0; }