Oulipo
题意:现有一个单词w,统计该单词在字符串s中出现了几次;
KMP算法就是匹配字符串的,可以O(n+m)的复杂度计算出单词是否在s中出现;那么统计次数???匹配到一次就返回上一次匹配的初始位置的下一个字符重新匹配???这不是又成了O(nm)的复杂度了嘛!还是没有深入理解KMP算法;当我们匹配完一遍后,前边的[0, next[m]]就无需重新匹配了,所以直接j返回到next[m]就ok了;
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int nxt[maxn];
void cal_next(char *s, int len){
nxt[0]=-1;
int j=0, k=-1;
while(j<len){
if(k==-1||s[k]==s[j]) j++, k++, nxt[j]=k;
else k=nxt[k];
}
}
int KMP(char *s1, int n, char *s2, int m){
cal_next(s2, m);
int i, j=0, cnt=0;
for(i=0; i<n; i++){
while(j&&s1[i]!=s2[j]) j=nxt[j];
if(s1[i]==s2[j]) j++;
if(j==m){
cnt++;
j=nxt[j];
}
}
return cnt;
}
char s[maxn], t[maxn];
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%s%s", s, t);
int n=strlen(s), m=strlen(t);
int ans=KMP(t, m, s, n);
printf("%d\n", ans);
}
return 0;
}