核心代码(求next数组和extend数组):

const int N=5e4+5;
char s1[N],s2[N];
int nxt[N],extend[N];
void getNext(char s[])//模式串
{
    int ls=strlen(s),i=0;
    nxt[0]=ls;
    while(i<ls&&s[i]==s[i+1])
        i++;
    nxt[1]=i;
    int k=1;//已知的最大匹配的开始位置
    for(int i=2;i<ls;i++)
    {
        int len=k+nxt[k];//已知的最大匹配的结束位置
        nxt[i]=min(nxt[i-k],max(0,len-i));
        while(i+nxt[i]<ls&&s[nxt[i]]==s[i+nxt[i]])//如果已知的最大匹配不能满足要求,继续判断
            nxt[i]++;
        if(i+nxt[i]>k+nxt[k])//更新已知的最大匹配
            k=i;
    }
}
void getExtend(char sa[],char sb[])//主串,模式串
{//与求next数组的步骤一样,不够是两个不同的字符串之间
    getNext(sb);
    int i=0,la=strlen(sa),lb=strlen(sb);
    while(sa[i]==sb[i]&&i<la&&i<lb)
        i++;
    extend[0]=i;
    int k=0;
    for(int i=1;i<la;i++)
    {
        int len=k+extend[k];
        extend[i]=min(nxt[i-k],max(0,len-i));
        while(i+extend[i]<la&&extend[i]<lb&&sb[extend[i]]==sa[i+extend[i]])//多了一个条件
            extend[i]++;
        if(i+extend[i]>k+extend[k])
            k=i;
    }
}

模板题:
Simpsons’ Hidden Talents HDU - 2594
可以用KMP解决:
KMP--------代码:

#include <bits/stdc++.h>
using namespace std;
const int N=5e4+5;
char s1[N],s2[N];
int nxt[N];
void getNext()
{
    int len=strlen(s1);
    int i=0,j=-1;
    nxt[0]=-1;
    while(i<len)//比一般的要多计算一位next数组值
    {
        if(j==-1||s1[i]==s1[j])
            nxt[++i]=++j;
        else
            j=nxt[j];
    }
}
int main()
{
    while(scanf("%s%s",s1,s2)!=EOF)
    {
        getNext();
        int i=0,j=0,len1=strlen(s1),len2=strlen(s2);
        while(i<len2)//因为要求s2的后缀,所有s2必须匹配完全
        {
            if(j==-1||(s1[j]==s2[i]&&j<len1))
                i++,j++;
            else
                j=nxt[j];
        }
        for(int i=0;i<j;i++)
        {
            printf("%c",s1[i]);
            if(i==j-1)
                printf(" ");
        }
        printf("%d\n",j);
    }
    return 0;
}

拓展KMP-----代码:

#include <bits/stdc++.h>
using namespace std;
const int N=5e4+5;
char s1[N],s2[N];
int nxt[N],extend[N];
void getNext(char s[])//模式串
{
    int ls=strlen(s),i=0;
    nxt[0]=ls;
    while(i<ls&&s[i]==s[i+1])
        i++;
    nxt[1]=i;
    int k=1;//已知的最大匹配的开始位置
    for(int i=2;i<ls;i++)
    {
        int len=k+nxt[k];//已知的最大匹配的结束位置
        nxt[i]=min(nxt[i-k],max(0,len-i));
        while(i+nxt[i]<ls&&s[nxt[i]]==s[i+nxt[i]])//如果已知的最大匹配不能满足要求,继续判断
            nxt[i]++;
        if(i+nxt[i]>k+nxt[k])//更新已知的最大匹配
            k=i;
    }
}
void getExtend(char sa[],char sb[])//主串,模式串
{//与求next数组的步骤一样,不够是两个不同的字符串之间
    getNext(sb);
    int i=0,la=strlen(sa),lb=strlen(sb);
    while(sa[i]==sb[i]&&i<la&&i<lb)
        i++;
    extend[0]=i;
    int k=0;
    for(int i=1;i<la;i++)
    {
        int len=k+extend[k];
        extend[i]=min(nxt[i-k],max(0,len-i));
        while(i+extend[i]<la&&extend[i]<lb&&sb[extend[i]]==sa[i+extend[i]])//多了一个条件
            extend[i]++;
        if(i+extend[i]>k+extend[k])
            k=i;
    }
}
int main()
{
    while(scanf("%s%s",s1,s2)!=EOF)
    {
        getExtend(s2,s1);
        int len=strlen(s2);
        int ans=0;
        for(int i=0;i<len;i++)
        {
            if(i+extend[i]==len)
            {
                ans=extend[i];
                break;
            }
        }
        for(int i=0;i<ans;i++)
            printf("%c",s1[i]);
        if(ans>0)
            printf(" ");
        printf("%d\n",ans);
    }
    return 0;
}

Clairewd’s message HDU - 4300
AC代码:

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
char s[30],text[N],sp[30];
int nxt[N],extend[N];
void getNext(char ss[])
{
    int ls=strlen(ss),i=0;
    nxt[0]=ls;
    while(i<ls&&ss[i]==ss[i+1])
        i++;
    nxt[1]=i;
    int k=1;
    for(int i=2;i<ls;i++)
    {
        int len=k+nxt[k];
        nxt[i]=min(nxt[i-k],max(0,len-i));
        while(i+nxt[i]<ls&&ss[nxt[i]]==ss[i+nxt[i]])
            nxt[i]++;
        if(i+nxt[i]>k+nxt[k])
            k=i;
    }
}
void getExtend(char sa[],char sb[])
{
    getNext(sb);
    int la=strlen(sa),lb=strlen(sb),i=0;
    while(s[sa[i]-'a']==sb[i]&&i<la&&i<lb)
        i++;
    extend[0]=i;
    int k=0;
    for(int i=1;i<la;i++)
    {
        int len=k+extend[k];
        extend[i]=min(nxt[i-k],max(0,len-i));//把nxt[i]写成了extend[i],t了几个小时
        while(i+extend[i]<la&&extend[i]<lb&&s[sa[i+extend[i]]-'a']==sb[extend[i]])
            extend[i]++;
        if(i+extend[i]>k+extend[k])
            k=i;
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",s);
        scanf("%s",text);
        memset(nxt,0,sizeof(nxt));
        memset(extend,0,sizeof(extend));
        getExtend(text,text);
        int len=strlen(text);
        int p=len;
        for(int i=0;i<26;i++)
            sp[s[i]-'a']=('a'+i);
        for(int i=0;i<len;i++)
        {
            if(i>=extend[i]&&extend[i]==len-i)
            {
                p=i;
                break;
            }
        }
        cout<<text;
        for(int i=len-p;i<p;i++)
            cout<<sp[text[i]-'a'];
        cout<<endl;
    }
    return 0;
}