题目描述
如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置。
为了减少骗分的情况,接下来还要输出子串的前缀数组next。
(如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习一下就知道了。)
输入输出格式
输入格式:
第一行为一个字符串,即为s1
第二行为一个字符串,即为s2
输出格式:
若干行,每行包含一个整数,表示s2在s1中出现的位置
接下来1行,包括length(s2)个整数,表示前缀数组next[i]的值。
输入输出样例
说明
时空限制:1000ms,128M
数据规模:
设s1长度为N,s2长度为M
对于30%的数据:N<=15,M<=5
对于70%的数据:N<=10000,M<=100
对于100%的数据:N<=1000000,M<=1000000
样例说明:
所以两个匹配位置为1和3,输出1、3
分析:
模板题还需要多说么。。。事实上是我也不知道说什么。。。
CODE:
1 // luogu-judger-enable-o2 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <iostream> 6 #include <algorithm> 7 using namespace std; 8 const int M=1000005; 9 char a[M],b[M]; 10 int p[M],n,m; 11 void pre(){ 12 p[1]=0; 13 int j=0; 14 for (int i=1;i<m;i++){ 15 while (j>0&&b[j+1]!=b[i+1]) j=p[j]; 16 if (b[j+1]==b[i+1]) j++; 17 p[i+1]=j; 18 } 19 } 20 void kmp(){ 21 int j=0; 22 for (int i=0;i<n;i++){ 23 while (j>0&&b[j+1]!=a[i+1]) j=p[j]; 24 if (b[j+1]==a[i+1]) j++; 25 if (j==m){ 26 cout<<i+1-m+1<<endl; 27 j=p[j]; 28 } 29 } 30 } 31 int main(){ 32 scanf ("%s%s",a+1,b+1); 33 n=strlen(a+1); 34 m=strlen(b+1); 35 pre(); 36 kmp(); 37 for (int i=1;i<=m;i++) 38 printf ("%d ",p[i]); 39 system("pause"); 40 return 0; 41 }