• 扩展KMP(占位)


    先放代码。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int N = 101010;
    int next[N],extand[N];
    void getnext(char *T){// next[i]: 以第i位置开始的子串 与 T的公共前缀 
         int i,length = strlen(T);
         next[0] = length;
         for(i=0;i<length-1&&T[i]==T[i+1];i++);
         next[1]=i;
         int a=1;
         for(int k = 2; k < length; k++){
              int p = a+next[a]-1, L = next[k-a];
              if( (k-1)+L >= p ){
                  int j = (p-k+1)>0? (p-k+1) : 0; 
                  while(k+j<length && T[k+j]==T[j]) j++;// 枚举(p+1,length) 与(p-k+1,length) 区间比较 
                  next[k] = j, a = k;
              } 
              else next[k] = L;
        } 
    }
    void getextand(char *S,char *T){
        memset(next,0,sizeof(next)); 
        getnext(T); 
        int Slen = strlen(S), Tlen = strlen(T), a = 0;
        int MinLen = Slen>Tlen?Tlen:Slen;
        while(a<MinLen && S[a]==T[a]) a++;
        extand[0] = a, a = 0;
        for(int k = 1; k < Slen; k++){
            int p = a+extand[a]-1, L = next[k-a];  
            if( (k-1)+L >= p ){
                int j = (p-k+1)>0? (p-k+1) : 0; 
                while(k+j<Slen && j<Tlen && S[k+j]==T[j] ) j++; 
                extand[k] = j;a = k; 
            } 
            else extand[k] = L;         
        }
    }
    
    int main(){
        char s[N],t[N];
        while(~scanf("%s %s",s,t)){
            getextand(s,t); 
            for(int i = 0; i < strlen(t); i++)
                printf("%d ",next[i]);
            puts(""); 
            for(int i = 0; i < strlen(s); i++)
                printf("%d ",extand[i]);
            puts("");
        } 
        return 0;
    }

    下标从1开始。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int N = 101010;
    int next[N],extand[N];
    char S[N],T[N];
    void getnext(){// next[i]: 以第i位置开始的子串与T的公共前缀长度 
         int i,length=strlen(T+1);
         next[1]=length;
         for(i=0;i+1<length&&T[i+1]==T[i+2];i++);
         next[2]=i;
         int a=2;   //!
         for(int k=3;k<=length;k++){//长度+1,位置-1。 
              int p=a+next[a]-1, L=next[k-a+1];
              if(L>=p-k+1){
                  int j=(p-k+1)>0?(p-k+1):0;//中断后可能是负的 
                  while(k+j<=length&&T[k+j]==T[j+1]) j++;// 枚举(p+1,length) 与(p-k+1,length) 区间比较 
                  next[k]=j, a=k;
              } 
              else next[k]=L;
        } 
    }
    void getextand(){
        memset(next,0,sizeof(next)); 
        getnext(); 
        int Slen=strlen(S+1),Tlen=strlen(T+1),a=0;
        int MinLen=Slen>Tlen?Tlen:Slen;
        while(a<MinLen&&S[a+1]==T[a+1]) a++;
        extand[1]=a, a=1;
        for(int k=2;k<=Slen;k++){
            int p=a+extand[a]-1,L=next[k-a+1];
            if(L>=p-k+1){
                int j=(p-k+1)>0?(p-k+1):0; 
                while(k+j<=Slen&&j<Tlen&&S[k+j]==T[j+1]) j++; 
                extand[k]=j;a=k; 
            }
            else extand[k]=L;    
        }
    }
    
    int main(){
        while(~scanf("%s %s",S+1,T+1)){
            getextand(); 
            for(int i=1;i<=strlen(T+1);i++)
                printf("%d ",next[i]);
            puts(""); 
            for(int i=1;i<=strlen(S+1);i++)
                printf("%d ",extand[i]);
            puts("");
        } 
        return 0;
    }
    View Code
  • 相关阅读:
    channel分析
    Nginx|基础
    item2
    搜索引擎技巧
    计算机网络|概述
    操作系统|进程
    分布式事务一致性
    画图工具StartUML
    内存分配
    MPG分析
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8523320.html
Copyright © 2020-2023  润新知