您的位置:首页 > 其它

KMP模版:子串是否出现

2017-09-18 20:04 232 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: