POJ2406 solution to a problem --KMP entry title (flexible use next array)

Topic links: http://poj.org/problem?id=2406

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 is 
AAAA 
ababab 
.

Sample Output

1
4
3

Hint

This problem has huge input, use scanf instead of cin to avoid time limit exceed.
 
Title meaning: find the string in each string up to the same number string consisting of connected end to end.
Topic ideas:
  KMP the next clever use of the array. Here we assume that the length of the string is len, len if it can be len-next [len] divisible, then we can say len-next [len] is the shortest length of the substring. why? Suppose we have a string ABABAB, then the next [6] = 4, right, due to the nature next is the match fails, the next can be continued matched positions, i.e., the first four letters of the string, abab, translation two units, the original string abab abab necessarily coincide (or do not meet the nature of the failure function), which explains what, because the whole string translation, and post-translational have to overlap, will there s [1] = s [3], s [2] = s [4], s [3] = s [5], s [4] = s [6]. Description string of length 2 in the original string in certain repeated, this is len-next [len] meaning!
  The same can be considered (see above may not understand): According to the origin of the next array, we can know the next [len] is the largest the same prefix suffix from 0 to len-1, below, we can see circled the largest part is the same prefixes and suffixes. Then we can be sure len-next [len] (double line designated portion) is the shortest substring recurring.
 
#include<stdio.h>
#include<string.h>
using namespace std;
const int maxn=1e7+10;
char str[maxn];
int next[maxn];
void GetNext(char *p)
{
	int plen=strlen(p);
	next[0]=-1;
	int k=-1;
	int j=0;
	while(j<plen)
	{
		if(k==-1||p[j]==p[k])
		{
			++k;
			++j;
			next[j]=k;
		}
		else k=next[k];
	}
}
int main()
{
	while(scanf("%s",str)!=EOF)
	{
		if(str[0]=='.')return 0;
		GetNext(str);
		int ans=1;
		int len=strlen(str);
		if(len%(len-next[len])==0)ans=len/(len-next[len]);
		printf("%d\n",ans);
	}
	return 0;
}
 

Guess you like

Origin www.cnblogs.com/Mingusu/p/11789945.html