zoukankan      html  css  js  c++  java
  • kmp基础 ekmp

      

    int nex[100000+5];
    int lenp,lens;
    int p[10000+5];//可以是char 也可以是string
    int s[1000000+5];
    void getnext()
    {
        nex[0]=-1;
        int k=-1,j=0;
        while(j<lenp-1)
        {
            if(k==-1||p[j]==p[k])
                nex[++j]=++k;
            else k=nex[k];
        }
    }
    int kmp()
    {   
        //lens=
        //lenp=
        int j=0;
        int i=0;
        while(i<lens&&j<lenp)
        {
            if(s[i]==p[j]||j==-1)
            {
                i++;
                j++;
            }
            else
                j=nex[j];
    
            if(j==lenp)
            {
                return i-j+1;
            }
        }
        return -1;
    }

    ekmp 注意  

    使用extend数组时  下标为0-len-1

    extend 意义:   entend[i]为主串第i个位置和副串开头匹配的位数

    int q,nxt[N],extend[N];
    string s,t;
    
    void getnxt()
    {
        nxt[0]=t.size();//nxt[0]一定是T的长度
        int now=0;
        while(t[now]==t[1+now]&&now+1<(int)t.size())now++;//这就是从1开始暴力
        nxt[1]=now;
        int p0=1;
        for(int i=2;i<(int)t.size();i++)
        {
            if(i+nxt[i-p0]<nxt[p0]+p0)nxt[i]=nxt[i-p0];//第一种情况
            else
            {//第二种情况
                int now=nxt[p0]+p0-i;
                now=max(now,0);//这里是为了防止i>p的情况
                while(t[now]==t[i+now]&&i+now<(int)t.size())now++;//暴力
                nxt[i]=now;
                p0=i;//更新p0
            }
        }
    }
    
    void exkmp()
    {
        getnxt();
        int now=0;
        while(s[now]==t[now]&&now<min((int)s.size(),(int)t.size()))now++;//暴力
        extend[0]=now;
        int p0=0;
        for(int i=1;i<(int)s.size();i++)
        {
            if(i+nxt[i-p0]<extend[p0]+p0)extend[i]=nxt[i-p0];//第一种情况
            else
            {//第二种情况
                int now=extend[p0]+p0-i;
                now=max(now,0);//这里是为了防止i>p的情况
                while(t[now]==s[i+now]&&now<(int)t.size()&&now+i<(int)s.size())now++;//暴力
                extend[i]=now;
                p0=i;//更新p0
            }
        }
    }
    
    int main()
    {
        cin>>s>>t;
        exkmp();
        int len=t.size();
        for(int i=0;i<len;i++)printf("%d ",nxt[i]);//输出nxt
        puts("");
        len=s.size();
        for(int i=0;i<len;i++)printf("%d ",extend[i]);//输出extend
        return 0;
    }
    View Code

    例子:https://www.luogu.org/problemnew/show/P5410

  • 相关阅读:
    [Vijos] 天才的记忆
    [Vijos] 河蟹王国
    [Vijos] SuperBrother打鼹鼠
    [Vijos] 弱弱的战壕
    [洛谷P3792] 由乃与大母神原型和偶像崇拜
    【模板】乘法逆元
    [USACO13NOV]空荡荡的摊位Empty Stalls
    [USACO08OPEN]牛的车Cow Cars
    [SCOI2005]扫雷
    [USACO16OPEN]关闭农场Closing the Farm_Silver
  • 原文地址:https://www.cnblogs.com/bxd123/p/10672940.html
Copyright © 2011-2022 走看看