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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值