1. 程式人生 > >POJ-2406 Power Strings(KMP求重複子串出現的最大次數)

POJ-2406 Power Strings(KMP求重複子串出現的最大次數)

Power Strings
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 50744 Accepted: 21173

Description

Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the empty string) and a^(n+1) = a*(a^n).

Input

Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.

Output

For each s you should print the largest n such that s = a^n for some string a.

Sample Input

abcd
aaaa
ababab
.

Sample Output

1
4
3

Hint

This problem has huge input, use scanf instead of cin to avoid time limit exceed.
/*
題意: 給出一個字串s,求重複子串出現的最大次數
分析:kmp的next[]陣列的應用
要求重複子串出現的最大次數,其實就是要求字串的最小迴圈節

這裡我們假設這個字串的長度是len,那麼如果len可以被len-next[len]整除的話,我們就可以說
len-next[len]就是那個最短子串的長度


為什麼呢? 假設我們有一個字串 ababab 那麼next[6]=4,  由於next的性質,匹配失配後,下一個能繼續進行匹配的位置,
也就是說,把字串的前四個字母,abab,平移2個單位,這個abab一定與原串的abab重合(否則就不滿足失敗函式的性質),zhejiu shuomi
題目分析轉載於:http://bbezxcy.iteye.com/blog/1377787
*/
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stdio.h>
using namespace std;

const int maxn =1e6+10;
int next[maxn];     /// 串的next陣列 (看這個串的相似度)
char s1[maxn];

void kmp_pre(char x[],int m,int next[])
{
    int i,j;
    j=next[0]=-1;
    i=0;
    while(i<m){
        while(-1!=j&&x[i]!=x[j])j=next[j];
        next[++i]=++j;
    }
}

int main()
{
    while(scanf("%s",s1)!=EOF)
    {
        memset(next,0,sizeof(next));
        if(s1[0]=='.')break;
        int len=strlen(s1);
        kmp_pre(s1,len,next);
        int temp=len-next[len];
        if(len%temp==0)printf("%d\n",len/temp);
        else printf("1\n");
    }
    return 0;
}