题意:
- 输入的第一个串为模式串,第二个串为文本串 它问,第一个串中能匹配到第二个串的后缀的最大前缀是什么,输出这个前缀和其长度。
做法:
- 扩展KMP模板题
- 扩展KMP:用来求文本串所有后缀与模式串的LCP
- 详细教程:扩展KMP算法
AC代码:
#include<bits/stdc++.h>
#define IO ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define pb(x) push_back(x)
#define sz(x) (int)(x).size()
#define sc(x) scanf("%d",&x)
#define abs(x) ((x)<0 ? -(x) : x)
#define all(x) x.begin(),x.end()
#define mk(x,y) make_pair(x,y)
#define fin freopen("in.txt","r",stdin)
#define fout freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int mod = 1e9+7;
const double PI = 4*atan(1.0);
const int maxm = 1e8+5;
const int maxn = 5e4+5;
const int INF = 0x3f3f3f3f;
const ll LINF = 1ll<<62;
char t[maxn];
char p[maxn];
int nex[maxn];
int extend[maxn];
void get_nex(char *p,int m)
{
nex[0] = m;
int j = 0;
while(j+1<m && p[j] == p[j+1]) j++;
nex[1] = j;
int k = 1;
for(int i=2;i<m;i++){
int pos = nex[k]+k-1;
int l = nex[i-k];
if(i+l < pos+1) nex[i] = l;
else{
j = max(0,pos-i+1);
while(i+j<m && p[i+j] == p[j]) j++;
nex[i] = j;
k = i;
}
}
}
void exkmp(char *t,char *p,int n,int m)
{
get_nex(p,m);
int j = 0;
while(j<n && j<m && t[j] == p[j]) j++;
extend[0] = j;
int k = 0;
for(int i=1;i<n;i++){
int pos = extend[k]+k-1;
int l = nex[i-k];
if(i+l<pos+1) extend[i] = l;
else{
j = max(0,pos-i+1);
while(i+j<n && j<m && t[i+j] == p[j]) j++;
extend[i] = j;
k = i;
}
}
}
int main()
{
// fin;
IO;
while(cin>>p>>t)
{
int m = strlen(p),n = strlen(t);
exkmp(t,p,n,m);
int ans = 0;
for(int i = n-1;i>=0;i--)
{
if(extend[i] == n-i)
ans = max(ans,extend[i]);
}
for(int i=0;i<ans;i++) cout<<p[i];
if(ans>0) cout<<" "<<ans<<endl;
else cout<<ans<<endl;
}
return 0;
}