POJ_2406_KMP

来源:互联网 发布:国家外汇管理局 知乎 编辑:程序博客网 时间:2024/05/22 01:59

Problem 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

思路

要求子串中重复子串的个数(即一模一样的子字符串有多少个)。
用kmp每次求得的next值就是当前到i为止的前子串与后子串相等的长度。
这道题巧用next数组性质,所以要对next数组怎样得来,以及它的性质做到了解。
重复子串的长度计算:if(len%(len-next[len])==0),则重复子串的长度为 len-next[len].
next[len]是表示到 len为止,满足前缀子串和后缀子串的最长长度,则len-next[len]就是最短的那个循环节长度,len除以最短的长度即得到重复子串的个数。

代码

#include <iostream>#include <cstdio>#include <string.h>using namespace std;int len;char str[50000005];int next[50000005];void get_next(char *str,int next[505]){    int i=0;//前缀    int j=-1;//后缀    next[0]=-1;     while(i<len)    {        if(j == -1|| str[j] == str[i])//j=-1或者当前匹配成功        {            i++;            j++;            next[i]=j;        }        else            j=next[j];    }    return ;}int main(){    while(scanf("%s",str)!=EOF)    {        if(strcmp(str,".")==0)            break;        len=strlen(str);        get_next(str,next);        if(len%(len-next[len]) == 0)            printf("%d\n",len/(len-next[len]));        else            printf("1\n");    }    return 0;}

KMP