今日拜读matrix67博客,学习了一下KMP算法,这是一种字符串匹配算法,可以在线性阶的复杂度下完成匹配,这个题目只是用到了匹配串的预处理,利用其中的p数组就可以完成此题,最后输出只需要满足(i+1)%(i-p[i]) == 0就可以输出了,这里可能会有人不太明白,这其实是一个化简公式,愿原公式为(i+1)%abs(p[i]+1-(2*(p[i]+1)-(i+1) ) ),其中2*(p[i]+1)-(i+1) 表示的是给定字符串中第i位中前p[i]个字符和后p[i]个字符有多少相交字符,然后用p[i]减去相交字符即得重复的字符长度,然后输出总长度i+1除以重复字符长度的值即可,代码如下:
# include <iostream>
using namespace std;
char a[1000100];
int p[1000100];
int main()
{
int n;
int TestCase = 0;
while (scanf("%d", &n) != EOF && n){
scanf("%s", a);
int len = strlen(a);
p[0] = -1;
int j = -1;
for (int i = 1; i < len; i ++){
while (j > -1&& a[j+1] != a[i]){
j = p[j];
}
if (a[j+1] == a[i])j ++;
p[i] = j;
}
//for (int i = 0; i <= len; i ++)printf("%d ", p[i]);
//printf("/n");
printf("Test case #%d/n", ++ TestCase);
for (int i = 1; i < len; i ++){
if (!((i+1)%(i-p[i]))&& p[i] != -1)printf("%d %d/n", i+1, (i+1)/(i-p[i]));
}
printf("/n");
}
return 0;
}