zoukankan      html  css  js  c++  java
  • 【模板】KMP字符串匹配

    终于搞懂KMP了!QAQ

    教材:KMP字符串匹配算法2_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili

    然后根据自己的理解写的代码↓

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 const int MAXN=1000007;
     6 char s[MAXN],t[MAXN];
     7 int nxt[MAXN];
     8 int main()
     9 {
    10     cin>>s>>t;
    11     int lens=strlen(s),lent=strlen(t);
    12     //make_nxt
    13     int len=0;
    14     int i=1;
    15     nxt[0]=0;
    16     while(i<lent){
    17         if(t[i]==t[len]){
    18             len++;
    19             nxt[i]=len;
    20             i++;
    21         }
    22         else{
    23             if(len){
    24                 len=nxt[len-1];
    25             }
    26             else{
    27                 nxt[i]=0;
    28                 i++;
    29             }
    30         }
    31     }
    32     //move_nxt
    33     for(int i=lent;i;--i)
    34     nxt[i]=nxt[i-1];
    35     nxt[0]=-1;
    36     //search
    37     int j=0;
    38     i=0;
    39     while(i<lens){
    40         if(j==lent-1){
    41             if(s[i]==t[j]){
    42                 cout<<i-j+1<<endl;
    43                 j=nxt[j];
    44             }
    45         }
    46         if(s[i]==t[j]){
    47             i++;j++;
    48         }
    49         else{
    50             if(j!=-1){
    51                 j=nxt[j];
    52             }
    53             else{
    54                 i++;j++;
    55             }
    56         }
    57     }
    58     //print
    59     for(int i=1;i<=lent;++i)
    60     cout<<nxt[i]<<" ";
    61     return 0;
    62 }
    View Code

    以及 这个代码确实很不优

    以前从网上抄的但根本写不出来的快很多的代码↓

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    char s1[1000007];
    char s2[1000007];
    int nex[1000007];
    int main()
    {
        //freopen("a.in","r",stdin);
        scanf("%s
    %s",&s1,&s2);
        int p,k,i,j,len1=strlen(s1),len2=strlen(s2);
        k=-1;
        nex[0]=-1;
        for(p=1;p<len2;++p)
        {
            while(k>-1&&s2[k+1]!=s2[p])k=nex[k];
            if(s2[k+1]==s2[p])k++;
            nex[p]=k;
        }
        k=-1;
        for(p=0;p<len1;++p)
        {
            while(k>-1&&s2[k+1]!=s1[p])k=nex[k];
            if(s2[k+1]==s1[p])k++;
            if(k==len2-1){printf("%d
    ",p-len2+2);k=-1;p=p-len2+1;}
        }
        for(i=0;i<len2;++i)
        printf("%d ",nex[i]+1);
        return 0;
    }
    View Code

    其实里面的思路都差不多,但是在模板题「LuoguP3375」【模板】KMP字符串匹配 上测,有差不多翻倍的时间差距。

    不过用for这样搞确实没有while好想好打(逃

    18.10.6 UPD:

    今天考试 有30分给的KMP

    我硬是没想起来自己理解的超长代码,随手背出了网上抄的那个

    真香

  • 相关阅读:
    poj2229 Sumsets (递推)
    hihocoder1148 February 29(区间闰年计数)
    sort函数比较cmp写法
    字符串忽略大小写
    地形
    启用和禁用warning
    AppStore SDK
    NGUI List优化
    ETC1
    加载
  • 原文地址:https://www.cnblogs.com/qwerta/p/9483712.html
Copyright © 2011-2022 走看看