博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

洛谷P3375 [模板]KMP字符串匹配

To 洛谷.3375 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

代码:

最新提交:

模式串为p,主串为s,代码中写反了。对p求fail。

 1 // luogu-judger-enable-o2
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int N=1e6+5;
 6 
 7 int fail[N];
 8 char s[N],p[N];
 9 
10 void Get_Fail()
11 {
12     fail[0]=fail[1]=0;
13     int l=strlen(s+1);
14     for(int j=0,i=2; i<=l; ++i)
15     {
16         while(j && s[i]!=s[j+1]) j=fail[j];
17         fail[i]= s[i]==s[j+1]?++j:0;
18     }
19 }
20 void KMP()
21 {
22     int l=strlen(p+1),ls=strlen(s+1);
23     for(int i=1,j=0; i<=l; ++i)
24     {
25         while(j && p[i]!=s[j+1]) j=fail[j];
26         if(p[i]==s[j+1]) ++j;
27         if(j==ls) printf("%d\n",i-ls+1);
28     }
29     for(int i=1; i<=ls; ++i)
30         printf("%d ",fail[i]);
31 }
32 
33 int main()
34 {
35     scanf("%s%s",p+1,s+1);
36     Get_Fail();
37     KMP();
38 
39     return 0;
40 }

旧的:

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 char s1[1000020],s2[1020];
 5 int len1,len2,fai[1020];
 6 void getfail()
 7 {
 8     fai[0]=fai[1]=0;
 9     for(int i=1;i<len2;i++)
10     {
11         int j=fai[i];
12         while(j&&s2[i]!=s2[j]) j=fai[j];
13         fai[i+1]= s2[i]==s2[j] ? j+1 : 0;
14     }
15 }
16 void kmp()
17 {
18     int j=0;
19     for(int i=0;i<len1;i++)
20     {
21         while(j&&s1[i]!=s2[j]) j=fai[j];
22         if(s1[i]==s2[j]) ++j;
23         if(j==len2)
24           printf("%d\n",i-len2+2);
25     }
26 }
27 int main()
28 {
29     scanf("%s",s1);
30     scanf("%s",s2);
31     len1=strlen(s1);
32     len2=strlen(s2);
33     getfail();
34     kmp();
35     for(int i=1;i<=len2;i++)
36       printf("%d ",fai[i]);
37     return 0;
38 }

 

[2018.4.4] :更新后的模板

 1 #include <cstdio>
 2 #include <cstring>
 3 const int N=1e6+5;
 4 
 5 int len,fail[N];
 6 char p[N],s[N];
 7 
 8 void Get_fail()
 9 {
10     fail[0]=0;
11     for(int i=1,j; i<len; ++i)
12     {
13         j=fail[i];
14         while(s[i]!=s[j]&&j) j=fail[j];
15         fail[i+1]=s[i]==s[j]?j+1:0;
16     }
17 }
18 void KMP()
19 {
20     for(int i=0,j=0,l=strlen(p); i<l; ++i)
21     {
22         while(p[i]!=s[j]&&j) j=fail[j];
23         if(p[i]==s[j]) ++j;
24         if(j==len) printf("%d\n",i-j+2);
25     }
26     for(int i=1; i<=len; ++i) printf("%d ",fail[i]);
27 }
28 
29 int main()
30 {
31     scanf("%s%s",p,s), len=strlen(s), Get_fail(), KMP();
32     return 0;
33 }

 

posted @ 2017-04-29 13:04  SovietPower  阅读(147)  评论(0编辑  收藏  举报