hdu1358 Period

来源:互联网 发布:网络媒介的优点 编辑:程序博客网 时间:2024/04/20 01:42

今日拜读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;   
}