【题解】Simpsons’ Hidden Talents HDU - 2594⭐⭐ 【扩展KMP】

Simpsons’ Hidden Talents HDU - 2594

求S1的前缀和S2的后缀的《最大》匹配

Input

多组输入,第一行S1,第二行S2。
S1和S2的长度小于50000。

Output

输出一行。
如果没有匹配,那么只输出一个0。
反之,输出匹配的字符串和匹配长度。中间一个空格间隔。

Examples

Sample Input
clinton
homer
riemann
marjorie
Sample Output
0
rie 3

Hint




题解:

很容易联想到e-KMP的extend数组, 求S[i…N-1]同T的最大前缀匹配, 是道e-KMP裸题没错了
但有细节需要注意一下, 这里要求S的后缀与T的前缀匹配, 只有在extend[i]+i==N时才说明是一个后缀匹配
枚举一下找一下最值就好了

往上似乎有更简单的做法, 但是我这个也不复杂吧

经验小结:


#include
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef  long long LL;
const int inf = 1 << 30;
const int maxn = 5e4 + 10;

char S[maxn], T[maxn];
int nxt[maxn], extend[maxn], N, M;
void getNext() {
    int a = 0, p = 0;
    nxt[0] = M;
    for (int i = 1; i < M; i++) {
        if (i >= p || i + nxt[i - a] >= p) {
            if (i >= p)
                p = i;
            while (p < M && T[p] == T[p - i])
                p++;
            nxt[i] = p - i;
            a = i;
        } else
            nxt[i] = nxt[i - a];
    }
}

void getExtend() {
    int a = 0, p = 0;
    getNext();
    for (int i = 0; i < N; i++) {
        if (i >= p || i + nxt[i - a] >= p) { //i>=p:例S 和 T 无一字符相同
            if (i >= p)
                p = i;
            while (p < N && p - i < M && S[p] == T[p - i])
                p++;
            extend[i] = p - i;
            a = i;
        } else
            extend[i] = nxt[i - a];
    }
}
int main() {
    while(scanf("%s", T) != EOF){
        scanf(" %s", S);
        N = strlen(S), M = strlen(T);
        getExtend();
        int ans = 0, tag = 0;
        for(int i = 0; i < N; ++i)
            if(extend[i]+i==N && extend[i] > ans)
                ans = extend[i], tag = i;
        if(!ans)
            printf("0\n");
        else{
            for(int i = tag; i < tag+ans; ++i)
                printf("%c",S[i]);
            printf(" %d\n",ans);
        }
    }
    return 0;
}

你可能感兴趣的:(数据结构)