Oulipo (哈希)

HDU - 1686 

求模式串在待匹配串的出现次数。

Input

第一行是一个数字T,表明测试数据组数。
之后每组数据都有两行:第一行为模式串,长度不大于10000;第二行为待匹配串,长度不大于1000000。所有字符串只由大写字母组成。

Output

每组数据输出一行结果。

Sample Input

4
ABCD
ABCD
ABA
ABABABA
CDCDCDC
CDC
KMP
NAIVE

Sample Output

1
3
0
0

这道题用哈希算法可以做,用KMP则更加方便,现贴出两种ac代码:

hsah:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const long long mod = 1e9+7;
const int MAXN = 1e6+10;
const int MAXM = 1e4+10;
char T[MAXN],W[MAXM];
int main(){
	int n;
	cin>>n;
	while(n--){
		scanf("%s %s",&W,&T);
		int len1=strlen(W);
		int len2=strlen(T);
		ll ans=0;
		ll s=0;
		ll sum=0;
		int p=223;
		for(int i=0;i<len1;i++){
			s=(s*p+W[i]-'A'+1)%mod;
		}
		for(int i=0;i<=len2-len1;i++){
			sum=0;
			if(T[i]==W[0]){
				for(int j=i;j<i+len1&&j<len2;j++){
					sum=(sum*p+T[j]-'A'+1)%mod;
				}
				if(sum==s){
					ans++;
				}
			}
		}
		printf("%lld\n",ans);
	}
	return 0;
}

KMP:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1e6+7;
char W[MAXN],T[MAXN];
int nxt[MAXN];
void getnxt(int m){
	int i=1,j=0;
	nxt[0]=0;
	while(i<m){
		if(W[i]==W[j]) nxt[i++]=++j;
		else if(!j) i++;
		else j=nxt[j-1];
	}
}
int kmp(int m,int n){
	int i=0,j=0;
	int ans=0;
	while(i<n){
		if(T[i]==W[j]) {
			i++;
			j++;
		}
		else if(!j) i++;
		else   j=nxt[j-1];
		if(j==m) ans++;
	}
	return ans;
}

int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%s %s",W,T);
		int len1=strlen(W);
		int len2=strlen(T);
		getnxt(len1);
		printf("%d\n",kmp(len1,len2));
		
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_42759455/article/details/82054310