题意:给出两个字符串,求其中一个在另一个中出现的次数(不可重复匹配)
思路:由于是不可重复的,所以相对于POJ-3461 (允许重复匹配),kmp的移动要进行修改,此时就将子串的下标置为0重新开始匹配即可
完整代码:
#include <iostream> #include <cstdio> using namespace std; const int maxn = 1e4+10; int num[100*maxn]; int num1[maxn]; int nex[maxn]; int N,M; int k,len1,len2,ans=-1; //求子字符串的nex数组 void getnex(){ int i=0,j=-1; nex[i]=j; while(i<len2){ if(j==-1||num1[i]==num1[j]){ i++;j++; nex[i]=j; } else j=nex[j]; } } int KMP(){ int i = 0, j = 0; getnex(); while(i < N && j < M) { if(j == -1 || num[i] == num1[j]) { i++; j++; } else j = nex[j]; } if(j == M) return i -M + 1; else return -1; } int main(){ ios::sync_with_stdio(0); cin.tie(0); int T; cin>>T; while(T--){ cin>>N>>M; for(int i=0;i<N;i++) cin>>num[i]; for(int i=0;i<M;i++) cin>>num1[i]; len1 = N ,len2 = M; ans = KMP(); cout<<ans<<endl; } }