Description

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 参考代码:

#include <cstdio>

#include <cstring>

const int maxn = 1000010;

int p[maxn],ans[maxn];

char str[maxn]; //保存字符串的数组

void get_p(int len){

p[1] = 0;

int j = 0;

for(int i = 2;i <= len;i++){

while(j > 0 && str[j+1] != str[i])  j = p[j];

//这个循环是当结果失配时才使用的

if(str[j+1] == str[i])  j++;

p[i] = j;

}

}

int main(){

int nkase;

scanf("%d",&nkase);

for(int kase = 1;kase <= nkase;kase++){

scanf("%s",str+1);

// 这个+1表示的含义是从下标为1的地方开始输入,方便后续的操作

//像C中这样控制字符串输入的格式还是非常方便的

int len = strlen(str+1);

get_p(len);

//这个是单单初始化了数组p得到了结果,然后主要的思想未知,可能是在求解next数组

//将str的长度告诉函数,通过匹配的方式得到数组p,相当于next数组

int t = p[len],cnt = 0;

while(t){

ans[cnt++] = len-t;

t = p[t];

//每次取到的数值是一定会比以前的要小,所以这不可能是一个死循环的

}

ans[cnt++] = len;

//在这里将所有的运算结果全部保留下来,包括数量cnt和最后输出的结果ans[];

printf("Case #%d: %d\n",kase,cnt);

//在这里有两个参数,即运行的次数和返回的结果数

for(int i = 0;i < cnt-1;i++)  printf("%d ",ans[i]);

printf("%d\n",ans[cnt-1]);

}

return 0;

}

关键点分析:

本题还是要先找到next数组,然后通过next数组来访问求解。

当然,每个next数组保存的内容都是不一样的,都是前一个字符匹配得到的信息结果保留在那个地方。

//KMP的算法重点就是求解next数组,当求解next数组时要知道关键点就是next数组中保存的数据是什么意思,那是当失配的时候后缀部分和前面的部分是否相同的表现

最新文章

  1. LINQ 联查多表数据并封装到ViewModel的实现
  2. mnsday1t1
  3. bzoj1799: [Ahoi2009]self 同类分布
  4. [聚类算法] K-means 算法
  5. 写给自己看的Linux运维基础(一) - 系统基础
  6. swift1.2语言函数和闭包函数介绍
  7. Ubuntu安装后的一些配置
  8. Mybatis 学习-4
  9. struts2视频学习笔记 11-12(动态方法调用,接收请求参数)
  10. ASP.NET 相关小知识
  11. 一个简单的shell脚本
  12. 在Window和Linux下使用Zthread库
  13. 关于mpu6050的几个很好的帖子
  14. 【Linux】windows-linux、linux-linux文件互传
  15. 基于 WebGL 3D 的 HTML5 档案馆可视化管理系统
  16. python rtree包查找三维空间下的最近设备
  17. 自定义控件详解(四):Paint 画笔路径效果
  18. bzoj2565: 最长双回文串 pam
  19. idea在哪执行maven clean?
  20. Java多线程之CountDownLatch和CyclicBarrier同步屏障的使用

热门文章

  1. c++中小项堆声明和使用【转】
  2. 初识SilkTest
  3. 分布式版本控制系统Git-----3.图形化Tortoisegit创建本地库并且提交到远程服务器上
  4. .net 中HttpClient 携带cookie传输
  5. Redis断线重连编码注意事项
  6. 第六十七节,html表单元素
  7. Apache Kafka开发入门指南(2)
  8. 《JS权威指南学习总结--第六章 对象》
  9. Spring Security(12)——Remember-Me功能
  10. (转)URI与URL的区别