码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-03-02 01:12:23      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:int   cstring   ext   har   target   blog   using   tar   ons   

题目链接: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求公共前后缀)

标签:int   cstring   ext   har   target   blog   using   tar   ons   

原文地址:https://www.cnblogs.com/fu3638/p/8491138.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!