Simpsons’ Hidden Talents
Problem Description
Write a program that, when given strings s1 and s2, finds the longest prefix of s1 that is a suffix of s2.
Sample Input
clinton homer
riemann marjorie
Sample Output
0
rie 3
思路:要求的是s1的最长前缀是s2的后缀;那么kmp中的getfail()就是用前缀来的匹配以当前点为尾点的子串的。那么如果我们 s1 += s2;那么所谓的s2的子串,就是len的匹配在s1长度总的f[i];
理解f[i]:当你那i+1的f[i+1]时,这是匹配的就是T[i] = p[i]了;
坑点:当 |s1| < |s2|时,f[i] <= |s2| ; 还有就是TLE有时不是太慢了。。而是空间炸了。。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N = 50007; char T[N<<1],p[N]; int f[N<<1]; void getfail(char* p) { f[0] = f[1] = 0; int n = strlen(p); for(int i = 1;i < n;i++){ int j = f[i]; if(j && p[i] != p[j]) j = f[j]; f[i+1] = (p[i] == p[j] ?j+1:0);// i+1会递推到第n位 } } int main() { while(scanf("%s%s",T,p) == 2){ int n = strlen(T),m = strlen(p),ans = 0; strcat(T,p); getfail(T); for(int j = n+m;j >= n || j >= m;j = f[j]){// n+m的f[]就是匹配后缀 //cout<<f[j]<<" "; if(f[j] <= n && f[j] <= m){ ans = f[j]; break; } } if(ans) for(int i = 0;i < ans;i++) putchar(T[i]); if(ans) putchar(' '); printf("%d\n",ans); } }