For each prefix with length P of a given string S,if
S[i]=S[i+P] for i in [0..SIZE(S)-p-1],
then the prefix is a “period” of S. We want to all the periodic prefixs.
Input
Input contains multiple cases.
The first line contains an integer T representing the number of cases. Then following T cases.
Each test case contains a string S (1 <= SIZE(S) <= 1000000),represents the title.S consists of lowercase ,uppercase letter.
Output
For each test case, first output one line containing "Case #x: y", where x is the case number (starting from 1) and y is the number of periodic prefixs.Then output the lengths of the periodic prefixs in ascending order.
Sample Input
4 ooo acmacmacmacmacma fzufzufzuf stostootssto
Sample Output
Case #1: 3 1 2 3 Case #2: 6 3 6 9 12 15 16 Case #3: 4 3 6 9 10 Case #4: 2 9 12 一开始写的时候不小心把求ans数组写成了递归,导致overflow。
#include<iostream> #include<set> #include<map> #include<vector> #include<string> #include<algorithm> #include<cstring> using namespace std; #define MAXN 1001000 /* 寻找字符串中所有 前缀 和(后缀逆转) 的匹配 将字符串逆转后 添加到原字符串末尾 然后输出所有小于源字符串长度的解 */ char s[MAXN]; int Next[MAXN],l,cnt; int ans[MAXN]; void kmp_pre(int m) { int j,k; j = 0; k = Next[0] = -1; while(j<m) { if(k==-1||s[j]==s[k]) Next[++j] = ++k; else k = Next[k]; } } void Cnt(int p) { while(Next[p]>=0) { ans[cnt++] = l-Next[p]; p = Next[p]; } } int main() { int T; scanf("%d",&T); for(int i=1;i<=T;i++) { cnt = 0; scanf("%s",s); l = strlen(s); kmp_pre(l); Cnt(l); printf("Case #%d: %d\n",i,cnt); for(int j=0;j<cnt;j++) { if(j) printf(" "); printf("%d",ans[j]); } cout<<endl; } }
时间: 2024-10-12 07:45:32