The little cat is so famous, that many couples tramp over hill and dale to Byteland, and asked the little cat to give names to their newly-born babies. They seek the name, and at the same time seek the fame. In order to escape from such boring job, the innovative little cat works out an easy but fantastic algorithm:
Step1. Connect the father’s name and the mother’s name, to a new string S.
Step2. Find a proper prefix-suffix string of S (which is not only the prefix, but also the suffix of S).
Example: Father=‘ala’, Mother=‘la’, we have S = ‘ala’+‘la’ = ‘alala’. Potential prefix-suffix strings of S are {‘a’, ‘ala’, ‘alala’}. Given the string S, could you help the little cat to write a program to calculate the length of possible prefix-suffix strings of S? (He might thank you by giving your baby a name:)
Input
The input contains a number of test cases. Each test case occupies a single line that contains the string S described above.
Restrictions: Only lowercase letters may appear in the input. 1 <= Length of S <= 400000.
Output
For each test case, output a single line with integer numbers in increasing order, denoting the possible length of the new baby’s name.
Sample Input
ababcababababcabab
aaaaa
Sample Output
2 4 9 18
1 2 3 4 5
中文大意
这只小猫非常有名,以至于许多夫妇翻山越岭来到Byteland,并要求小猫给他们刚出生的婴儿起名字。他们追求名声,同时也追求名声。为了摆脱这种无聊的工作,创新的小猫想出了一个简单而神奇的算法:
Step1。将父亲的名字和母亲的名字连接到一个新的字符串 S。
Step2。找到合适的S的前后缀串(不仅是S的前缀,也是S的后缀)。
例如:Father=‘ala’,Mother=‘la’,我们有 S = ‘ala’+‘la’ = ‘alala’。S 的潜在前缀-后缀字符串是 {‘a’, ‘ala’, ‘alala’}。给定字符串 S,你能帮小猫写一个程序来计算 S 可能的前缀-后缀字符串的长度吗?(他可能会通过给你的宝宝起个名字来感谢你:)
输入
输入包含许多测试用例。每个测试用例占用一行,其中包含上述字符串 S。
限制:输入中只能出现小写字母。1 <= S 的长度 <= 400000。
输出
对于每个测试用例,输出一行以递增顺序的整数,表示新婴儿名字的可能长度。
样本输入
ababcababababcabab
aaaaa
样本输出
2 4 9 18
1 2 3 4 5
题目大意:本题输入为多实例,每组测试样例为一串字符,要求输出这个字符串的所有公共前后缀的长度,每个结果之间各一个空格,最后要求输出字符串的长度。
解题思路:再输入每组数据字符串之后,获取这个字符串的next数组,之后定义一个cns和ans数组用来存储答案,当next[slen]不等于0就把他存在ans之中,然后进行一个for循环,逆序输出ans,最后单独输出一个slen。
错误分析:注意最后要输出字符串的长度,注意求next数组的时候先把next【0】复制为-1。
实现代码:
include
include
include
using namespace std;
char str[800010];
int Next[800010];//注意next在程序中有特有的意义,这里注意区别一下
int ans[800010];
int slen;
void gtnext()
{
int k=-1;int j=0;
while(j<slen)
{
if(k==-1||str[j]==str[k])
{
j++,k++;
Next[j]=k;
}
else k=Next[k];
}
return ;
}//这是kmp中很基础的一种求解next数组的模板
int main()
{
while(cin>>str)
{
slen=strlen(str);
Next[0]=-1;//不要忘记先把next[0]赋值为-1,这一步也可以放在函数体里面,不容易忘
gtnext();
int cnt=0;
int tp=slen;
while(Next[tp]!=0)
{//即这个字符串有公共前后缀
ans[cnt++]=Next[tp];
tp=Next[tp];//存储答案的过程
}
for(int i=cnt-1; i>=0; i--)
cout<<ans[i]<<" ";
cout<<slen<<endl;//注意最后输出字符串的长度
}
}