KMP模版:子串是否出現

caioj《===主站鏈接

hzoj《===我的一個分站鏈接

其實你們可以用hzoj的,hzoj會快很多,我這裏每一題我都會發博客,都會在上面提交,基本上都有數據,起碼比你去其他地方找好得多。
【題意】 有兩個字符串SA和SB,SA是母串,SB是子串,問子串SB是否在母串SA中出現過。 如果出現過輸出第一次出現的起始位置和結束位置,否則輸出"NO" 【輸入文件】 第一行SA(1 <= 長度 <= 100 0000) 第二行SB(1 <= 長度 <= 1000) 【輸出文件】 如果SB在SA中出現過輸出第一次出現的起始位置和結束位置,否則輸出"NO" 【樣例1輸入】 aaaaabaa aab 【樣例1輸出】 4 6 【樣例2輸入】 aaaaabaa aax 【樣例2輸出】 NO
這個主要還算是用kmp的p數組進行處理,p數組意味着什麼,假如p[i]爲4就是代表以i結尾的長度爲4的後綴與長度爲4的前綴相等。 然後可以通過p來一步一步拓展就可以得到後面的。
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Maxchar 1000000
#define mes(x,y) memset(x,y,sizeof(x));
#define mpy(x,y) memcpy(x,y,sizeof(x))
#define INF 2147483647
using namespace std;
char sa[Maxchar+1],sb[Maxchar+1];
int lena,lenb,p[Maxchar+1];
int main(){
	scanf("%s",sa+1);lena=strlen(sa+1);
	scanf("%s",sb+1);lenb=strlen(sb+1);
	p[1]=0;int j;
	for(int i=2;i<=lenb;i++){
		j=p[i-1];
		while(j>0&&sb[i]!=sb[j+1])j=p[j];
		if(sb[i]==sb[j+1])p[i]=j+1;
		else p[i]=0;
	}
	int st,ed;
	j=0;
	for(int i=1;i<=lena;i++){
		while(j>0&&sa[i]!=sb[j+1])j=p[j];
		if(sa[i]==sb[j+1])j++;
		if(j==lenb){st=i-lenb+1;ed=i;break;}
	}
	if(j==lenb)printf("%d %d\n",st,ed);
	else printf("NO\n");
	return 0;
}
具體的我csdn《==進入csdn 裏面有其他關於kmp的很多幹貨。 省選訓練第一題加油

查看原文:http://hz2016.tk/blog/?p=18
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章