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

  • 相关阅读:
    iOS imageName方法获取Folder文件夹(蓝色文件夹)内图片
    iOS 使用AFNetworking框架检测当前网络连接状态
    iOS 使用Block实现界面间传值
    JAVA关键字
    十进制、八进制、二进制之间的转换
    CMake,win10,64位,简单配置测试
    win10 64位,家庭版,C++,ini配置说明
    win10 64 + VS2010 + Opencv 2.4.9 + HIKVISION(海康)
    ROS--导航、路径规划和SLAM
    ROS入门实例---5安装ROS-By-Example
  • 原文地址:https://www.cnblogs.com/bxd123/p/10672940.html
Copyright © 2011-2022 走看看