题目大意:
输入一个T,表示有T组测试数据;
每组测试数据包括一个字符串W,T,T长度大于W小于1000000,w长度小于10000,计算W匹配到T中成功的次数;
这题很明显要用KMP算法,不然很容易超时,但在使用kmp算法时也要注意,我第一次将匹配成功的位置得到后,循环进入kmp算法,从前一个匹配到的位置开始算起,但是超时了。后来问完学长之后,清楚了,没必要循环进入kmp,直接一次可以搞定,每次模式串匹配到末尾时,都将计数+1,然后根据next[m],重新得到j继续与原串进行匹配直到进行到原串结束。
代码如下:
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 using namespace std; 6 7 char b[10100]; 8 char a[1000100]; 9 int next[10100]; 10 int n,m,count; 11 12 void getNext(char *b) 13 { 14 int j; 15 next[0]=0,next[1]=0; 16 for(int i=1;i<m;i++){ 17 j=next[i]; 18 while(j&&b[j]!=b[i]) j=next[j]; 19 if(b[j]==b[i]) next[i+1]=j+1; 20 else next[i+1]=0; 21 } 22 } 23 24 void kmp(char *a,char *b,int *next) 25 { 26 int j=0; 27 for(int i=0;i<n;i++){ 28 29 while(j&&a[i]!=b[j]) j=next[j]; 30 if(a[i]==b[j]) j++; 31 if(j==m) count++,j=next[j]; 32 } 33 } 34 35 int main() 36 { 37 int T; 38 cin>>T; 39 while(T--){ 40 count=0; 41 string W,T; 42 cin>>W>>T; 43 n=T.size(); 44 m=W.size(); 45 for(int i=0;i<n;i++){ 46 a[i]=T.at(i); 47 } 48 for(int i=0;i<m;i++){ 49 b[i]=W.at(i); 50 } 51 52 getNext(b); 53 kmp(a,b,next); 54 cout<<count<<endl; 55 } 56 return 0; 57 }