POJ 2752 Seek the Name, Seek the Fame(KMP求公共前后缀)

Posted Yeader

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2752 Seek the Name, Seek the Fame(KMP求公共前后缀)相关的知识,希望对你有一定的参考价值。

题目链接:http://poj.org/problem?id=2752

题目大意:给你一串字符串s找到所有的公共前后缀,即既是前缀又是后缀的子串。

解题思路:

如图所示

 

假设字符串pi与jq为符合条件的一组公共前后缀,那么易得pi=jq,如下图所示

若在字符串pi内,pk1与k2i为公共前后缀,有因为pi=jq所以对应的k2i在字符串jq内有后缀k4q与其等价。所以pi内的公共前后缀等也是pq的公共前后缀,而i=next[q],显然是个递归。

所以,可以通过不断使pos=next[pos]进行递归求出所有的公共前后缀。这里其实利用了一些next[]数组的对称性质。

代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<map>
 5 #include<string>
 6 using namespace std;
 7 const int N=1e6+5;
 8 
 9 int m;
10 int nxt[N],ans[N];
11 char p[N];
12 
13 void getnext(){
14     int i,j;
15     i=0,j=nxt[0]=-1;
16 
17     while(i<m){
18         while(j!=-1&&p[i]!=p[j])
19             j=nxt[j];
20         nxt[++i]=++j;
21     }
22 }
23 
24 int main(){
25     while(~scanf("%s",p)){
26         m=strlen(p);
27         getnext();
28         int cnt=0;
29         ans[cnt++]=m;
30         int t=m;
31         while(t!=-1){
32             if(nxt[t]>0)
33                 ans[cnt++]=nxt[t];
34             t=nxt[t];
35         }
36         for(int i=cnt-1;i>=0;i--){
37             printf("%d%c",ans[i],i==0?\'\\n\':\' \');
38         }
39     }
40     return 0;
41 }

 

以上是关于POJ 2752 Seek the Name, Seek the Fame(KMP求公共前后缀)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2752 Seek the Name, Seek the Fame(KMP求公共前后缀)

POJ 2752 Seek the Name, Seek the Fame

POJ2752 Seek the Name, Seek the Fame

POJ 2752 Seek the Name, Seek the Fame

poj2752 Seek the Name, Seek the Fame

poj 2752 Seek the Name, Seek the Fame