POJ1961_Peroid_KMP_求最多的子串重复次数

/*

吐槽君又来吐槽了,额= =这就是我两天来学习KMP的成果,水了一道水题,还是照着模版,看着题解写的=i=唯一的成就就是我植物大战僵尸的水平又更上一层楼,对自己无语了,暑假集训俨然要过半了,自己期待的蜕变却越来越远,希望明天能有新变化,今晚早睡

*/

言归正传:

题意:

给一个字符串长为n,i从1到n,对与每一个i,找出从str[0]到str[i-1]内的一个最短子串s,使得当前串是由子串s循环k次组成的,输出当前i与k,当k<=1时不输出

 

题解:

第一次做KMP,看了很多博客和ppt讲解,现在还是晕晕乎乎的= =,这道题是考察对next数组的理解与运用,我是参照POJ2406的题解做的,那个题就是求s最多能拆成几个子串,这里只不过不止求s,还把所有长度的母串都求了一遍

题意转化为,找到最小的L,使得s[L]....s[n-1]=s[0]......s[n-1-L]

在s串后添加\0,则L=strlen(s)-next[n];//这里需要好好理解一下

例:

s:   abababab

              abababab

next[8]=6;

L=2;

 

求next的函数是照着维基百科上面给的模版写的

伪代码如下:

/*

algorithmkmp_table:

  input:

    an array of characters, W (the word to be analyzed)

    an array of integers, T (the table to be filled)

  output:

    nothing (but during operation, it populates the table)define variables:

    an integer, pos ← 2 (当前要计算T数组元素)

    an integer,cnd ← 0 (辅助变量,满足

    W[0..cnd-1]=W[pos-cnd-1..pos-2])

  let T[0] ← -1, T[1] ← 0

while pos is less than the length of W, do:

  (first case: the substring continues)

  if W[pos - 1] = W[cnd],
 
letcndcnd + 1, T[pos] ←cnd, pos ← pos + 1

  (second case: it doesn't, but we can fall back)

  otherwise,ifcnd > 0,

    letcnd ← T[cnd]

  (third case: we have run out of candidates. Notecnd = 0)

  otherwise,let T[pos] ← 0, pos ← pos + 1

 

*/

原题题目:

Period
Time Limit: 3000MS   Memory Limit: 30000K
Total Submissions: 11016   Accepted: 5075

Description

For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string. That is, for each i (2 <= i <= N) we want to know the largest K > 1 (if there is one) such that the prefix of S with length i can be written as A K ,that is A concatenated K times, for some string A. Of course, we also want to know the period K.

Input

The input consists of several test cases. Each test case consists of two lines. The first one contains N (2 <= N <= 1 000 000) – the size of the string S.The second line contains the string S. The input file ends with a line, having the
number zero on it.

Output

For each test case, output "Test case #" and the consecutive test case number on a single line; then, for each prefix with length i that has a period K > 1, output the prefix size i and the period K separated by a single space; the prefix sizes must be in increasing order. Print a blank line after each test case.

Sample Input

3
aaa
12
aabaabaabaab
0

Sample Output

Test case #1
2 2
3 3

Test case #2
2 2
6 2
9 3
12 4

Run ID User Problem Result Memory Time Language Code Length Submit Time
11772450 chengtbf 1961 Accepted 7964K 719MS C++ 945B 2013-07-12 22:09:04

代码:

 

#include
#include
#define N 1000005

int count,n;
int str[N];
int next[N];
void get_next()
{
	next[0]=-1;next[1]=0;
	int pos=2;//用来记录数组下标
	int cnd=0;//辅助变量,满足str[0]......str[cnd-1]=str[pos-cnd-1].........str[pos-2]
	while (pos<=n)
	{
		if (str[pos-1]==str[cnd])
		{
			cnd++;
			next[pos]=cnd;
			pos++;
		}
		else if(cnd>0)
		{
			cnd=next[cnd];
		}
		else
		{
			next[pos]=0;
			pos++;
		}
	}
}
	
int main()
{
	int i,len;
	char temp;
	count=0;
	while (1)
	{
		count++;
		scanf("%d",&n);
		if (n==0)
		{
			break;
		}
		scanf("%c",&temp);
		for ( i = 0; i =2)
			{
				printf("%d %d\n",i,i/len);
			}
		}
		printf("\n");
	}
	return 0;

}


 

 

你可能感兴趣的:(KMP)