zoukankan      html  css  js  c++  java
  • 扩展KMP 洛谷P5410 模板

    题目链接:https://www.luogu.org/problem/P5410

    题意:给两个字符串a,b,求b对a的每一个后缀的最大前缀长度

    分析:扩展KMP(又称Z-algorithm算法)裸题

    该博客讲解的比较好:https://www.luogu.org/blog/lc-2018-Canton/solution-p5410

    但他有几个地方讲的有几个问题,主要在情况2里面

    首先是一开始S[K+L]肯定是在p的后面,这个比较明显

    然后情况二红蓝绿三条线的序列不是一样的,红绿还是一样的,但是蓝线就不等了,这个自己看一看

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+7;//单词间自行添加了符号,稍做扩大 
    const ll inf=1e18;
    #define meminf(a) memset(a,0x3f,sizeof(a))
    #define mem0(a) memset(a,0,sizeof(a));
    char a[maxn],b[maxn];
    int nxt[maxn],extend[maxn];//nxt[i]代表b[i...len]和b的最大前缀长度,extend[i]代表a[i...len]和b的最大前缀长度 
    void getnxt(){
        int len=strlen(b);
        nxt[0]=len;//nxt[0]就是原串情况下,自然就为len
        int now=0;
        while(b[now]==b[now+1]&&now+1<len) now++;
        nxt[1]=now;
        int p0=1;//p0是满足p0+nxt[p0]-1最大的点,一开始初始化为1 
        for(int i=2;i<len;i++){
            if(i+nxt[i-p0]<p0+nxt[p0]) nxt[i]=nxt[i-p0];
            //i相当于k+1,nxt[i-p0]相当于L(nxt[k-p0+2) 这里字符串是从0开始的,和博客里面从1开始的区别是少加一个1 
            else{
                int now=p0+nxt[p0]-i;
                now=max(now,0);//防止i在p的后面
                while(b[now]==b[i+now]&&i+now<len) now++;
                nxt[i]=now;
                p0=i;//更新p0 
            } 
        } 
    }
    void exkmp(){
        getnxt();
        int len=strlen(a);
        int now=0;
        while(a[now]==b[now]&&now<min(strlen(a),strlen(b))) now++;
        extend[0]=now;
        int p0=0;
        for(int i=1;i<len;i++){
            if(i+nxt[i-p0]<extend[p0]+p0) extend[i]=nxt[i-p0];
            else{
                int now=p0+extend[p0]-i;
                now=max(now,0);
                while(b[now]==a[i+now]&&now<strlen(b)&&i+now<len) now++;
                extend[i]=now;
                p0=i;
            }
        }  
    }
    int main(){
        scanf("%s%s",a,b);
        exkmp();
        for(int i=0;i<strlen(b);i++) printf("%d ",nxt[i]);
        putchar('
    ');
        for(int i=0;i<strlen(a);i++) printf("%d ",extend[i]);
        putchar('
    ');
        return 0;
    } 
  • 相关阅读:
    [转] linux下查看文件编码及修改编码
    offset Dimensions 详解
    style属性
    Using NodeLists
    Element Children
    Node、Document关系的探究
    Document、HTMLDocument关系的探究
    BOM Summary P268-P269
    Intervals and Timeouts
    Window Position
  • 原文地址:https://www.cnblogs.com/qingjiuling/p/11391630.html
Copyright © 2011-2022 走看看