标签:
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 16036 | Accepted: 8159 |
Description
Input
Output
Sample Input
ababcababababcabab aaaaa
Sample Output
2 4 9 18 1 2 3 4 5
此题意思是让输出字符串中所有具有相同前后缀时的字符串长度。
已知 next数组中存放的是当前字符之前的字符串中具有相同前后缀的长度,
例如:next[i]=5;表示从字符串开始到下标为 i-1时,具有长度为5的相同前后缀子串
字符串:ababcababababcabab
下标: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
字符: a b a b c a b a b a b a b c a b a b
next: -1 0 0 1 2 0 1 2 3 4 3 4 3 4 5 6 7 8 9
1、长度为 18 时,字符串为 ababcababababcabab,前缀 ababcabab,后缀 ababcabab,输出18;
2、长度为 9 时,字符串为 ababcabab,前缀 abab,后缀abab,输出 9;
3、长度为 4 时,字符串为 abab,前缀 ab,后缀 ab,输出 4;
4、长度为 2 时,字符串为 ab,前缀 a,后缀 b,此时前后缀不相同,输出此时的字符串长度 2,并结束;
(因为字符串是从后向前一一查找判断的,所以当找到不想同的前后缀时既查找完毕,输出并结束)
......
如果还不明白,我就仍然以上述例子说,next[18]=9;意思是说,此字符串有长度为 9 的相同前后缀, 如上 1 所示,
设字符串长度为 9,此时next[9]=4,表示在此长度为 9 的前缀中,又有长度为 4 的相同的前后缀,
设字符串长度为 4,此时next[4]=2;.............
依次进行....
具体代码: #include <stdio.h> #include <string.h> char s[400005]; int next[400005]; int ans[400005]; void Make_next(int len) { int i=0,j=-1; memset(next,0,sizeof(next)); next[0]=-1; while(i<len) { if(j==-1 || s[i]==s[j]) { i++; j++; next[i]=j; } else j=next[j]; } } int main() { while(scanf("%s",&s)!=EOF) { int len=strlen(s); Make_next(len); int i,j=0; memset(ans,0,sizeof(ans)); for(i=len;next[i]!=-1;)//直到找到没有前缀后缀相同为止 { ans[j++]=i;//记录具有相同前后缀时的字符串的长度 i=next[i]; } for(i=j-1;i>=0;i--) printf("%d ",ans[i]); printf("\n"); } return 0; }
标签:
原文地址:http://blog.csdn.net/liu940204/article/details/51333045