HDU---2594:Simpsons’ Hidden Talents(扩展KMP)

题意:

给你两个字符串,在第二个串中求一个最长的后缀,同时满足它是第一个串的前缀

分析:

刘雅琼---《扩展KMP》(一看就会)

扩展KMP:在线性的时间内,求出一个串的每个后缀与模式串的最长公共前缀

此题只需判断extend[i] == len - i,那么以i开始的后缀的每个字符都匹配了模式串的前缀

代码:

*#include <bits/stdc++.h>

using namespace std;
const int maxn = 5e4+13;
char s[maxn],t[maxn];
int nnext[maxn],extend[maxn];
void getnext(){
    int j = 0,tlen = strlen(t);
    nnext[0] = tlen;
    while(j+1 < tlen && t[j] == t[j+1]) j++;
    nnext[1] = j;
    int k = 1;
    for(int i = 2;i < tlen; ++i){
        int p = nnext[k] + k;
        int L = nnext[i-k];
        if(i + L < p) nnext[i] = L;
        else{
            j = max(p-i,0);
            while(i+j < tlen && t[j] == t[j+i]) j++;
            nnext[i] = j;
            k = i;
        }
    }
}
void EKMP(){
    int j = 0,tlen = strlen(t),slen = strlen(s);
    while(j < tlen && j < slen && s[j] == t[j]) j++;
    extend[0] = j;
    int k = 0;
    for(int i = 1;i < slen; ++i){
        int p = k + extend[k];
        int L = nnext[i-k];
        if(i+L < p) extend[i] = L;
        else{
            j = max(p-i,0);
            while(i+j < slen && j < tlen && s[i+j] == t[j]) j++;
            extend[i] = j;
            k = i;
        }
    }
}
int main(){
    while(~scanf("%s %s",t,s)){
        getnext();
        EKMP();
        int slen = strlen(s),start = slen;
        for(int i = 0;i < slen; ++i){
            if(extend[i] == slen-i){
                start = i;
                break;
            }
        }
        for(int i = start;i < slen; ++i) cout << s[i];
        if(slen - start) cout << " " << slen - start << '\n';
        else puts("0");
    }
    return 0;
}

 

猜你喜欢

转载自blog.csdn.net/qq_41157137/article/details/89174770
今日推荐