字符串匹配—KMP 扩展KMP Manacher

kuangbin字符串专题传送门--http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70325#overview

 

算法模板:

KMP:

const int MAXM=10010;
const int MAXN=1000010;
int a[MAXN],b[MAXM],Next[MAXM];
int n,m;

void getNext(int b[],int Next[])
{
    int j=0,k=-1;
    Next[0]=-1;
    while(j<m-1)
    {
        if(k==-1||b[j]==b[k]) //匹配
        {
            j++,k++;
            Next[j]=k;
        }
        else
            k=Next[k]; //不匹配
    }
}

int KMP(int a[],int b[])
{
    int i=0,j=0;
    getNext(b,Next);
    while(i<n)
    {
        if(j==-1||a[i]==b[j])
            i++,j++;
        else
            j=Next[j];
        if(j==m)
            return i-m+1;
    }
    return -1;
}


扩展KMP:

const int MAXN;
int Next[MAXN],extend[MAXN];
char a[MAXN],b[MAXN];

void getNext(char b[])
{
    int i,len=strlen(b);
    Next[0]=len;
    for(i=0;i<len-1&&b[i]==b[i+1];i++)
    {
        Next[1]=i;
        int tmp=1;
        for(int k=2;k<len;k++)
        {
            int p=tmp+Next[tmp]-1,L=Next[k-tmp];
            if((k-1)+L>=p)
            {
                int j=(p-k+1)>0?(p-k+1):0;
                while(k+j<len&&b[k+j]==b[j])
                    j++;
                Next[k]=j,tmp=k;
            }
            else Next[k]=L;
        }
    }
}

void getExtend(char a[],char b[])
{
    memset(Next,0,sizeof(Next));
    getNext(b);
    int lena=strlen(a),lenb=strlen(b),tmp=0;
    int minlen=lena<lenb?lena:lenb;
    while(tmp<minlen&&a[tmp]==b[tmp])
        tmp++;
    extend[0]=tmp,tmp=0;
    for(int k=1;k<lena;k++)
    {
        int p=tmp+extend[tmp]-1,L=Next[k-tmp];
        if((k-1)+L>=p)
        {
            int j=(p-k+1)>0?(p-k+1):0;
            while(k+j<lena&&j<lenb&&a[k+j]==b[j])
                j++;
            extend[k]=j,tmp=k;
        }
        else extend[k]=L;
    }
}


Manacher:

const int MAXN=110010;
char s1[MAXN],Mt[MAXN*2];
int Mp[MAXN*2];

int Manacher(int len,char s[])
{
    int Mx=0,id=0,L=0;
    int ret=0;
    Mt[L++]='$';Mt[L++]='#';
    for(int i=0;i<len;i++)
    {
        Mt[L++]=s[i];
        Mt[L++]='#';
    }
    Mt[L]=0;
    for(int i=1;i<L;i++)
    {
        if(Mx>i)
            Mp[i]=min(Mp[id*2-i],Mx-i);
        else
            Mp[i]=1;
        while(Mt[i+Mp[i]]==Mt[i-Mp[i]])
            Mp[i]++;
        if(Mp[i]+i>Mx)
        {
            Mx=Mp[i]+i;
            id=i;
        }
        if(Mp[i]-1>ret)
            ret=Mp[i]-1;
    }
    return ret;
}
原文地址:https://www.cnblogs.com/atmacmer/p/5440551.html