计蒜客 阿里天池的新任务—简单( KMP水 )


**链接:****传送门 **

思路:KMP模板题,直接生成 S 串,然后匹配一下 P 串在 S 串出现的次数,注意处理嵌套的情况即可,嵌套的情况即 S = "aaaaaa" ,P = "aa" P 串在S 串中出现了 5 次。


/*************************************************************************
    > File Name: jsk02e2.cpp
    > Author:    WArobot 
    > Blog:      http://www.cnblogs.com/WArobot/ 
    > Created Time: 2017年05月21日 星期日 10时28分09秒
 ************************************************************************/

#include<bits/stdc++.h>
using namespace std;

const int MAX_N = 1000100;
char S[MAX_N] , P[MAX_N];
int W[MAX_N];

void init(int n,int a,int b,int L,int R){
	W[0] = b;
	for(int i = 1 ; i < n ; i++)	W[i] = ( W[i-1] + a ) % n;
	for(int i = 0 ; i < n ; i++){
		if( W[i] >= L && W[i] <= R){
			if( W[i] & 1 )	S[i] = 'T';
			else			S[i] = 'A';
		}
		else{
			if( W[i] & 1 )  S[i] = 'C';
			else			S[i] = 'G';
		}
	}
}
// KMP部分
void Build_Next(const char* pat,int next[]){
	int i = 1 , t = 0 , plen = strlen(pat);
	next[1] = 0;
	while( i < plen + 1 ){
		while( t > 0 && pat[i-1]!=pat[t-1] )	t = next[t];
		++t , ++i;
		if( pat[i-1] == pat[t-1] )	next[i] = next[t];
		else						next[i] = t;
	}
	while( t > 0 && pat[i-1] != pat[t-1] )	t = next[t];
	++i , ++t;
	next[i] = t;
}
int KMP(const char* text , const char* pat){
	int i , j , n;
	int tlen = strlen(text) , plen = strlen(pat);
	int next[plen+2];
	Build_Next(pat,next);

	i = 0 , j = 1 , n = 0;
	while( plen + 1 - j <= tlen - i ){
		if( text[i] == pat[j-1] ){
			++i , ++j;
			if( j == plen + 1 ){
				// matches[n++] = i - plen;	// 发现匹配结果将匹配子串的位置加入结果集合
				n++;	j = next[j];
			}
		}
		else{
			j = next[j];
			if( j == 0 ){
				i++ , j++;
			}
		}
	}
	return n;
}
int main(){
	int n , a , b , L , R;
	scanf("%d%d%d%d%d",&n,&a,&b,&L,&R);
	scanf("%s",P);
	init(n,a,b,L,R);
	int ans = KMP(S,P);
	printf("%d
",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/WArobot/p/6886426.html