1. 问题描述:
一个长为N (2 <= N <= 1 000 000) 的字符串,问前缀串长度为k(k > 1)是否是一个周期串,即k = A...A;若是则按k从小到大的顺序输出k即周期数;
Sample Input
3 aaa
12 aabaabaabaab
0
Sample Output
Test case #1
2 2
3 3
Test case #2
2 2
6 2
9 3
12 4
2. 其实就是对KMP算法中的next数组的使用,假设next[j] = k
那么如果是周期字符串有:j % (j - k)余数为0那么认为这个字符串是周期性的,而且重复的次数:j / (j - k)
代码如下:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
List<String> list = new ArrayList<String>();
while (true) {
int n = sc.nextInt();
if (n == 0) {
break;
}
String s = sc.next();
list.add(s);
}
for(int j = 0; j<list.size();j++) {
String s = list.get(j);
int[] next = next(s);
for(int i = 0;i<next.length;i++){
System.out.print(next[i]+" ");
}
System.out.print("\n");
System.out.println("Test case #" + (j + 1));
boolean flag = false;
for(int i = 2; i < next.length; i++) {
int k = next[i];
int t = i - k;
if (i%t==0&&i/t>1){
System.out.println(i + " " + i / t);
}
}
// if (!flag) System.out.println(0+" "+0);
System.out.println();
}
}
private static int[] next(String s) {
if (s == null || s.length() == 0) return null;
int[] next = new int[s.length()+1];
next[0] = -1;
if (s.length() == 1)
return next;
next[1] = 0;
int j = 1;
int k = next[j];
while (j < s.length()) {
if (k == -1 || s.charAt(j) == s.charAt(k)) {
next[++j] = ++k;
} else {
k = next[k];
}
}
return next;
}
}