HDU 4300 Clairewd’s message(扩展KMP)

思路:extend[i]表示原串以第i開始与模式串的前缀的最长匹配。经过O(n)的枚举,我们能够得到,若extend[i]+i=len且i>=extend[i]时,表示t即为该点之前的串,c即为该点之前的str串,最后输出就可以。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
const int N=100010;

char s[N],t[N];
char c[N];
int next[N],extand[N];
void getNext(int lt)
{
    next[0]=lt;
    int a=0;
    while(a<lt-1&&t[a+1]==t[a]) a++;
    next[1]=a;
    a=1;
    for(int k=2;k<lt;k++)
    {
        int p=a+next[a]-1;
        int L=next[k-a];
        if(k-1+L>=p)
        {
            int j=(p-k+1)>0?

(p-k+1):0; while(j+k<lt&&t[k+j]==t[0+j]) j++; next[k]=j; a=k; } else next[k]=L; } } void getExtand(int ls,int lt) { getNext(lt); int a=0; int minLen=min(ls,lt); while(a<minLen&&t[a]==c[a]) a++; extand[0]=a; a=0; for(int k=1;k<ls;k++) { int p=a+extand[a]-1; int L=next[k-a]; if(k-1+L>=p) { int j=(p-k+1)>0?(p-k+1):0; while(j+k<ls&&j<lt&&t[j+k]==c[j]) j++; extand[k]=j; a=k; } else extand[k]=L; } } int main() { int T; cin>>T; while(T--) { cin>>s>>t; map<char,char> mmap; int lt=strlen(t); int ls=strlen(s); for(int i=0;i<ls;i++) mmap[s[i]]='a'+i; for(int i=0;i<lt;i++) c[i]=mmap[t[i]]; getExtand(lt,lt); int i; for(i=0;i<lt;i++) { if(i+extand[i]>=lt&&i>=extand[i]) break; } for(int j=0;j<i;j++) cout<<t[j]; for(int j=0;j<i;j++) cout<<c[j]; cout<<endl; } return 0; }



posted @ 2015-12-28 12:33  mengfanrong  阅读(174)  评论(0编辑  收藏  举报