题意:输出所有可能的循环节。
思路:对next数组的理解。
反思:一开始的想法是找出最小循环节len-next[len].然后用最小循环节来找所有可能的循环节。后来一直wa。用随机法打了一些表找到了一组能证明错误的数据ababaaaabab.用最小循环节来求答案是7,11,正确答案是7,9,11。最小循环节不能代表所有循环节。
一开始我的代码在找所有的循环节的时候,一旦当我遇到匹配不上的时候就会退出循环不再找了,其实还可以将未匹配的位置向左移动一位就又可以了,我原来的错误代码就因为如此漏了好多种情况
AC代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=1000005;
char s[maxn];
int nxt[maxn];//abcabcabc
void getnext(int len)
{
int i=1,j=0;
nxt[1]=0;
while(i<=len){
if(j==0||s[i]==s[j]){
i++;
j++;
nxt[i]=j;
}
else{
j=nxt[j];
}
}
}
int main()
{
int t;
scanf("%d",&t);
int C=1;
queue<int> q;
while(t--){
scanf("%s",s+1);
int len=strlen(s+1);
getnext(len);
int p;
while(!q.empty()){
q.pop();
}
int pre=len;
while(nxt[pre]>1){
if(s[pre]==s[nxt[pre]]){
q.push(len-nxt[pre]);
pre=nxt[pre];
}
else{
q.push(len-nxt[pre]+1);
pre=nxt[pre]-1;
}
}
if(nxt[pre]>0&&s[pre]==s[nxt[pre]]){
q.push(len-nxt[pre]);
}
q.push(len);
printf("Case #%d: %d\n",C++,q.size());
while(!q.empty()){
int ko=q.front();
if(q.size()==1)
printf("%d\n",ko);
else{
printf("%d ",ko);
}
q.pop();
}
}
return 0;
}
错误代码:
```cpp
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=1000005;
char s[maxn];
int nxt[maxn];//abcabcabc
void getnext(int len)
{
int i=1,j=0;
nxt[1]=0;
while(i<=len){
if(j==0||s[i]==s[j]){
i++;
j++;
nxt[i]=j;
}
else{
j=nxt[j];
}
}
}
int main()
{
int t;
scanf("%d",&t);
int C=1;
queue<int> q;
while(t--){
scanf("%s",s+1);
int len=strlen(s+1);
getnext(len);
int p;
if(s[len]==s[nxt[len]]){
p=len-nxt[len];
}
else{
p=len;
}
while(!q.empty()){
q.pop();
}
int pre=len;
while(nxt[pre]>0){
if(s[pre]==s[nxt[pre]]){
q.push(len-nxt[pre]);
pre=nxt[pre];
}
else{
break;//这一步是错的,当匹配不上时要向左移动一位,而不是跳出循环,原因都是nxt[]初始值不一样,为了避免麻烦,我们还可以将nxt[0]设为-1,也就是字符串下标从0开始,终于感受到求next[]时字符串下标从0开始的好处!!!
}
}
q.push(len);
printf("Case #%d: %d\n",C++,q.size());
while(!q.empty()){
int ko=q.front();
q.pop();
printf("%d ",ko);
}
printf("\n");
}
return 0;
}