在自己的CB上错了两次,然后改了之后提交就过了
错误原因第一个:
if(j==w.size()) {cmp++;j=0;}
因为想着当前字符串已经找到了一个了,所以重新初始化为0,但是实际上,这样想第一点——不符合KMP的思想(next数组)
第二点,会漏算,例如W=“aaa”,T="aaaaaaaaa",则cmp=3,实际上远远不止。
第二个:
while(i<t.size()) {
if(j==-1 || t[i]==w[j]){j++;i++;} else j=nexta[j]; } 判断写在了前面,这样WA在了样例的第二个的那种情况,也就是i=size && j=size,因为当i=size的时候会跳出循环了,就不会做判断了,也就是cmp不++了。if(j==w.size()) {cmp++;j=nexta[j];}
所以想清楚啥时候做判断。
AC代码:
#include <iostream> #include <stdio.h> #include <queue> #include <algorithm> #include <string> #include <cstring> #include <climits> using namespace std; const int maxm=10000+10; string w,t; int nexta[maxm]; void nextaa() { int i,k; i=0; k=-1; nexta[0]=-1; while(i<w.size()) { if(k==-1 || w[i]==w[k]){ if(w[i+1]==w[k+1]) nexta[++i]=nexta[++k]; else nexta[++i]=++k; } else k=nexta[k]; } } int kmp() { nextaa(); //cout<<"nexta[w.size]="<<nexta[w.size()]<<endl; int cmp=0; int i,j; i=j=0; while(i<t.size()) { if(j==-1 || t[i]==w[j]){j++;i++;} else j=nexta[j]; if(j==w.size()) {cmp++;j=nexta[j];} } return cmp; } int main(){ ios::sync_with_stdio(false); cin.tie(0); int test; cin>>test; while(test--){ memset(nexta,0,sizeof(nexta)); w.clear(); t.clear(); cin>>w; cin>>t; int ans=kmp(); cout<<ans<<endl; } return 0; }