zoukankan      html  css  js  c++  java
  • KMP~

    模板传送门

    KMP的模板,但是要输出Nxt,搞得朱洪dalao的优化打不了。(题外话)

    KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。

    简单来说,KMP算法的核心是求next数组,表示0~i点的最长相同前后缀的长度。

    用i表示文本串匹配到i位置,j表示模式串匹配到j位置。

    当S[i]!=P[j]时,j=next[j],即保持i不变,使j向前找到公共前缀来减少匹配次数。

    怎么求next呢?

    其实就是一个模式串自我匹配的过程。

    已知next[1~j],求next[j+1]。

    设next[j]=k;

    next[0]=k=-1;

    如果S[j]==S[k],j++,k++,next[j]=k。

    否则k=next[k],即向前递归。

    code:

    #include <cstdio>
    #include <string>
    #include <iostream>
    
    const int MAXN=1000000; 
    
    int nxt[MAXN];
    void get_nxt(std::string S)
    {
        int plen=S.size();
        nxt[0]=-1;
        int k=-1,j=0;
            while(j<plen){
                if(k<0 || S[j]==S[k])
                    k++,j++,nxt[j]=k;
                else k=nxt[k];
            }
        return ;
    }
    
    void Kmp(std::string S1,std::string S2)
    {
        int i=0,j=0,s1l=S1.size(),s2l=S2.size();
            while(i<s1l){
                if(j<0||S1[i]==S2[j])i++,j++;
                else j=nxt[j];
                if(j==s2l)printf("%d
    ",i-j+1),j=nxt[j];
            }
        return ;
    }
    
    int main()
    {
        std::string S1,S2;
        std::cin>>S1>>S2;
        get_nxt(S2);
        Kmp(S1,S2);
            for(int i=1;i<=S2.size();i++)
                printf("%d ",nxt[i]);
        return 0;
    }
  • 相关阅读:
    codeforces 616B Dinner with Emma
    codeforces 616A Comparing Two Long Integers
    codeforces 615C Running Track
    codeforces 612C Replace To Make Regular Bracket Sequence
    codeforces 612B HDD is Outdated Technology
    重写父类中的成员属性
    子类继承父类
    访问修饰符
    方法的参数
    实例化类
  • 原文地址:https://www.cnblogs.com/Cptraser/p/8533267.html
Copyright © 2011-2022 走看看