POJ2752 Seek the Name, Seek the Fame 【既是前綴又是後綴的子串】


【題目大意】

輸入一個僅含小寫字母的字符串,求出其子串的長度,該子串滿足條件:既是前綴又是後綴。輸入包含多組數據。

【解題思路】

分析題意,得知該題是求給定字符串的所有前綴後綴子串的長度。(以下將前綴後綴串簡稱爲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+性質判定。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章