拓展kmp模板

int nx[maxn],ex[maxn];
//nx[i]表示模式串T[i~len-1]与T的最长公共前缀
//ex[i]表示母串S[i~len-1]与T的最长公共前缀
char S[maxn],T[maxn];
int lent,lens;
void getNext(){
    nx[0]=lent;//本身匹配
    int j=0;
    while(j+1<lent&&T[j]==T[j+1]) j++;
    nx[1]=j;
    int k=1;//最远拓展位置的开始位置用k保存
    for(int i=2;i<lent;i++){
        int p=k+nx[k]-1;//最远拓展位置
        int l=nx[i-k];/*
        难点:因为 匹配:k~p<->0~p-k+1
              那么 i对应i-k
              那么next[i-k]就是从i开始去匹配原串(从0位置开始的长度)
        */
        //下面分两种情况讨论:
        if(i+l<p+1) nx[i]=l;//如果在最远匹配位置之内;
        else{//如果不在,记得更新;
            j=max(0,p-i+1);
            while(i+j<lent&&T[i+j]==T[j]) j++;//看p之外的位置是否匹配;
            nx[i]=j;
            k=i;
        }
    }
}
/*
求extend数组和求next数组基本一致;
*/
void exkmp(){
    int j=0;
    while(j<lens&&j<lent&&S[j]==T[j]) j++;
    ex[0]=j;
    int k=0;
    for(int i=1;i<lens;i++){
        int p=k+nx[k]-1;
        int l=nx[i-k];
        if(l+i<p+1) ex[i]=l;
        else{
            j=max(0,p-i+1);
            while(i+j<lens&&j<lent&&S[i+j]==T[j]) j++;
            ex[i]=j;
            k=i;
        }
    }
}
  


int nx[maxn],ex[maxn];
char S[maxn],T[maxn];
int lent,lens;
void getNext(){
    nx[0]=lent;
    int j=0;
    while(j+1<lent&&T[j]==T[j+1]) j++;
    nx[1]=j;
    int k=1;
    for(int i=2;i<lent;i++){
        int p=k+nx[k]-1;
        int l=nx[i-k];
        if(i+l<p+1) nx[i]=l;
        else{
            j=max(0,p-i+1);
            while(i+j<lent&&T[i+j]==T[j]) j++;
            nx[i]=j;
            k=i;
        }
    }
}
void exkmp(){
    int j=0;
    while(j<lens&&j<lent&&S[j]==T[j]) j++;
    ex[0]=j;
    int k=0;
    for(int i=1;i<lens;i++){
        int p=k+nx[k]-1;
        int l=nx[i-k];
        if(l+i<p+1) ex[i]=l;
        else{
            j=max(0,p-i+1);
            while(i+j<lens&&j<lent&&S[i+j]==T[j]) j++;
            ex[i]=j;
            k=i;
        }
    }
}

  

原文地址:https://www.cnblogs.com/imzscilovecode/p/8060210.html