【题目大意】
输入一个仅含小写字母的字符串,求出其子串的长度,该子串满足条件:既是前缀又是后缀。输入包含多组数据。
【解题思路】
分析题意,得知该题是求给定字符串的所有前缀后缀子串的长度。(以下将前缀后缀串简称为PS串(Prefix-Suffix))
显然,设B为A的PS串,则有A[i]=A[len-1](下标从零开始),其中A[i]为B的最后一位。
所以可以利用KMP优越的匹配性能直接从头开始匹配,如果某一位存在上述性质则存下来,最后倒序输出。
【代码】:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<cstring>
#include<string>
#include<cctype>
#include<iomanip>
//#define LOCAL
using namespace std;
const int N=400011;
int F[N];
char T[N];
int ans[N];
void Fail(char *T,int *F){
F[0]=-1;
int posm=strlen(T);
for (int i=1;i<posm;++i){
int j=F[i];
while (j&&T[i]!=T[j]) j=F[j];
F[i+1]=(T[i]==T[j]) ? j+1 : 0;
}
}
int main(){
#ifdef LOCAL
freopen("POJ2752.in","r",stdin);
#endif
while (scanf("%s",T)!=EOF){
Fail(T,F);
int len=strlen(T);
int zjl=F[len-1];
int cnt=0;
while (zjl!=-1){
if (T[zjl]==T[len-1]) ans[cnt++]=zjl+1;
zjl=F[zjl];
}
for (int i=cnt-1;i>=0;--i) printf("%d ",ans[i]);
printf("%d\n",len);
}
return 0;
}
【总结】
PS串的解决方法——直接KMP+性质判定。