扩展kmp

c.

/*
扩展kmp模板
*/
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

#define MaxSize 1024

int _next[MaxSize],extend[MaxSize];

//扩展kmp
//next[i]:x[i...m-1]与x[0...m-1]的最长公公前缀
//extend[i]:y[i...n-1]与x[0...m-1]的最长公共前缀
void pre_EKMP(char x[],int m,int _next[]){//m长度
    _next[0]=m;
    int j=0;
    while(j+1<m&&x[j]==x[j+1])j++;
    _next[1]=j;
    int k=1;
    for(int i=2;i<m;i++){
        int p=_next[k]+k-1;
        int L=_next[i-k];
        if(i+L<p+1)_next[i]=L;
        else{
            j=max(0,p-i+1);
            while(i+j<m&&x[i+j]==x[j])j++;
            _next[i]=j;
            k=i;
        }
    }
}

void EKMP(char x[],int m,char y[],int n,int _next[],int extend[]){//x子串,m子串长度,y主串,n主串长度
    pre_EKMP(x,m,_next);
    int j=0;
    while(j<n&&j<m&&x[j]==y[j])j++;
    extend[0]=j;
    int k=0;
    for(int i=1;i<n;i++){
        int p=extend[k]+k-1;
        int L=_next[i-k];
        if(i+L<p+1)extend[i]=L;
        else{
            j=max(0,p-i+1);
            while(i+j<n&&j<m&&y[i+j]==x[j])j++;
            extend[i]=j;
            k=i;
        }
    }
}
/*
子串  :a b a b
主串  :a b a b a c
next  :4 0 2 0
extend:4 0 3 0 1 0
*/

int main(){
    char str1[32],str2[32];//子串,主串
    int i,len1,len2;//子串长度,主串长度
    scanf("%s%s",str1,str2);
    len1=strlen(str1);
    len2=strlen(str2);
    EKMP(str1,len1,str2,len2,_next,extend);
    for(i=0;i<len1;++i)
        printf("%d ",_next[i]);
    printf("\n");
    for(i=0;i<len2;++i)
        printf("%d ",extend[i]);
    printf("\n");

    return 0;
}

 

你可能感兴趣的:(扩展kmp)