• 洛谷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 }

    无心插柳柳成荫才是美丽
    有哪种美好会来自于刻意
    这一生波澜壮阔或是不惊都没问题
    只愿你能够拥抱那种美丽

  • 相关阅读:
    正则表达式匹配中国区的电话号码
    落户
    存储过程与函数的区别转载
    asp.net页面从初始化到卸载事件顺序转
    .net连接Oracle数据库 常见问题
    sql触发器的类型
    (转) C++中extern “C”含义深层探索
    vmware 收缩越来越大的磁盘文件
    (转)一些常用的网站
    工具:P/Invoke Interop Assistant
  • 原文地址:https://www.cnblogs.com/SovietPower/p/6893616.html
Copyright © 2020-2023  润新知