P3375 【模板】KMP字符串匹配

 P3375 【模板】KMP字符串匹配

题目描述

如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置。

为了减少骗分的情况,接下来还要输出子串的前缀数组next。如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习一下就知道了。

输入输出格式

输入格式:

 

第一行为一个字符串,即为s1(仅包含大写字母)

第二行为一个字符串,即为s2(仅包含大写字母)

 

输出格式:

 

若干行,每行包含一个整数,表示s2在s1中出现的位置

接下来1行,包括length(s2)个整数,表示前缀数组next[i]的值。

 

输入输出样例

输入样例#1:
ABABABC
ABA
输出样例#1:
1
3
0 0 1 

说明

时空限制:1000ms,128M

数据规模:

设s1长度为N,s2长度为M

对于30%的数据:N<=15,M<=5

对于70%的数据:N<=10000,M<=100

对于100%的数据:N<=1000000,M<=1000

样例说明:

所以两个匹配位置为1和3,输出1、3

 

code

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 
 7 const int N = 10000100;
 8 int p[N],n,m; // p最长的公共前后缀 
 9 char A[N],B[N]; // A主串,B模式串 
10 
11 void get_p() {
12     p[1] = 0;
13     for (int i=2; i<=m; ++i) {
14         int j = p[i-1];
15         while (j && B[i]!=B[j+1]) j = p[j];
16         if (B[i] == B[j+1]) j++;
17         p[i] = j;
18     }
19 }
20 void kmp() {
21     int j = 0;
22     for (int i=1; i<=n; ++i) {
23         while (j && A[i]!=B[j+1]) j = p[j];
24         if (A[i]==B[j+1]) j++;
25         if (j==m) printf("%d\n",i-m+1);
26     }
27 }
28 int main () {
29     scanf("%s",A+1);
30     scanf("%s",B+1);
31     n = strlen (A+1);
32     m = strlen(B+1);
33     get_p();
34     kmp();
35     for (int i=1; i<=m; ++i) 
36         printf("%d ",p[i]);
37     return 0;
38 }

 

 

以前的代码

 1 #include<cstdio>
 2 #include<cstring>
 3 char a[1000100],b[1010];
 4 int s1,s2;
 5 int p[1010];
 6 void init()
 7 {
 8     int j=0;
 9     p[0]=0;
10     for(int i=1;i<s2;i++)
11     {
12         while(j>0&&b[j]!=b[i]) j=p[j-1];
13         if(b[j]==b[i]) j++;
14         p[i]=j;
15     }
16 }
17 void kmp()
18 {
19     int j=0;
20     for(int i=0;i<s1;i++)
21     {
22         if(j>0&&b[j]!=a[i]) j=p[j-1];
23         if(b[j]==a[i]) j++;
24         if(j==s2) printf("%d\n",i+1-s2+1);
25     }
26 }
27 int main()
28 {
29     scanf("%s%s",a,b);
30     s1=strlen(a);
31     s2=strlen(b);
32     init();
33     kmp();
34     for(int i=0;i<s2;i++)
35         printf("%d ",p[i]);
36     return 0;
37 }
View Code

 

 

 

posted @ 2017-05-23 21:41  MJT12044  阅读(210)  评论(0编辑  收藏  举报