http://acm.hdu.edu.cn/showproblem.php?pid=2594
EXKMP详解https://blog.csdn.net/dyx404514/article/details/41831947
EXKMP解法
裸题 存模板
#include <bits/stdc++.h>
using namespace std;
const int maxn=5e4+10;
int nxtt[maxn],nxts[maxn];
char ch1[maxn],ch2[maxn];
int n1,n2;
void exkmp(char *t,int lt)
{
int i,j,p;
nxtt[0]=lt;
i=0;
while(i+1<lt&&t[i]==t[i+1]) i++;
nxtt[1]=i;
p=1;
for(i=2;i<lt;i++){
if(i+nxtt[i-p]<p+nxtt[p]) nxtt[i]=nxtt[i-p];
else{
j=max(0,p+nxtt[p]-i);
while(i+j<lt&&t[j]==t[i+j]) j++;
nxtt[i]=j;
p=i;
}
}
}
void solve(char *s,int ls,char *t,int lt)
{
int i,j,p;
i=0;
while(i<ls&&i<lt&&s[i]==t[i]) i++;
nxts[0]=i;
p=0;
for(i=1;i<ls;i++){
if(i+nxtt[i-p]<p+nxts[p]) nxts[i]=nxtt[i-p];
else{
j=max(0,p+nxts[p]-i);
while(i+j<ls&&j<lt&&s[i+j]==t[j]) j++;
nxts[i]=j;
p=i;
}
}
}
int main()
{
int i,ans;
while(scanf("%s%s",ch1,ch2)!=EOF){
n1=strlen(ch1),n2=strlen(ch2);
exkmp(ch1,n1);
solve(ch2,n2,ch1,n1);
ans=0;
for(i=0;i<n2;i++){
if(i+nxts[i]==n2){
ans=nxts[i];
break;
}
}
if(ans>0){
for(i=0;i<ans;i++) printf("%c",ch1[i]);
printf(" ");
}
printf("%d\n",ans);
}
return 0;
}
KMP解法
也是裸题 nxts[i]代表后缀si与t的最长公共前缀
#include <bits/stdc++.h>
using namespace std;
const int maxn=5e4+10;
int nxtt[maxn],nxts[maxn];
char ch1[maxn],ch2[maxn];
int l1,l2;
void kmp(char *t,int lt)
{
int i,j;
nxtt[0]=-1;
i=0,j=-1;
while(i<lt){
if(j==-1||t[i]==t[j]){
i++,j++;
nxtt[i]=j;
}
else j=nxtt[j];
}
}
void solve(char *s,int ls,char *t,int lt)
{
int i,j;
i=0,j=0;
while(i<ls){
if(j==-1||s[i]==t[j]){
i++,j++;
nxts[i]=j;
if(j==lt) j=nxtt[j];
}
else j=nxtt[j];
}
}
int main()
{
int i,p,ans;
while(scanf("%s%s",ch1,ch2)!=EOF){
l1=strlen(ch1),l2=strlen(ch2);
kmp(ch1,l1);
solve(ch2,l2,ch1,l1);
if(nxts[l2]>0){
for(i=0;i<nxts[l2];i++){
printf("%c",ch1[i]);
}
printf(" ");
}
printf("%d\n",nxts[l2]);
}
return 0;
}
//aba babab