Oulipo HDU - 1686(KMP匹配,统计匹配串的个数)

Oulipo

题目链接:HDU - 1686

题意:现有一个单词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;
}

猜你喜欢

转载自blog.csdn.net/Sirius_han/article/details/81434675