Period UVALive - 3026(KMP)

对于一段字符串来说,如果存在循环节,那么它的最小循环节一定是 ( 字符串的长度i - Next[i] ) (相当于最后一个循环节),那么直接判断(i % ( i - Next[i] ))就可以判断是不是存在循环节,还要注意Next[] > 0


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

const int maxn = 1000005;
char str[maxn];
int Next[maxn];
int n ;
void KMP()
{
    Next[0] = 0, Next[1] = 0;
    for(int i = 1; i < n; i++)
    {
        int j = Next[i];
        while(j && str[i] != str[j]) j = Next[j];
        Next[i+1] = (str[i] == str[j] ? j+1 : 0);
    }
}
int main()
{
    int cas = 1;
    while(scanf("%d", &n) == 1 && n)
    {
        scanf("%s", str);
        KMP();
//        for(int i =  1 ;i <= n ; i++) cout << i << " " << Next[i] << endl;
        printf("Test case #%d\n", cas++);
        for(int i = 2; i <= n; i++)
            if(Next[i] > 0 && i % ( i - Next[i] ) == 0)
                printf("%d %d\n", i, i / (i - Next[i]));
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhaiqiming2010/article/details/78594926
今日推荐