以下是几种类型题:
A.类型1:匹配子字符串在母串中第几个位置开始出现。
B.类型2:子串在母串中出现了几次(可以有重复的)。
eg:子串:AZA
母串:AZAZAZA
ans = 3;
C.类型3:母串中最多有几个子串。
D.类型4:需要再补几个字符能构成一个类似手链那样循环相同的。
eg:abca ->2
abcde->5
aaa->0
E.类型5:给出一字符串,找出由2个或2个以上相同的子字符串组成的前缀,输出前缀长度及其相同的子字符串数。
F.类型6:当前最小循环节中字符串的个数(不可以补字符串)。
G.类型7:求最小循环节有几个。
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.
3 aaa 12 aabaabaabaab 0
Test case #1 2 2 3 3 Test case #2 2 2 6 2 9 3 12 4
AC代码:
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
int pext[1000000] = {-5};
char s[1000000];
int len1;
void get_next(char *T,int *next)
{
int k = -1;
int j = 0;
pext[j] = k;
while(j < len1)
{
if((k == -1) || (T[j] == T[k]))
{
k++;
j++;
pext[j] = k;
}
else
{
k = pext[k];
}
}
}
int main()
{
int n;
int o = 1;
while(scanf("%d",&n)!=EOF)
{
if(n == 0)
{
return 0;
}
else
{
scanf("%s",s);
printf("Test case #%d\n",o++);
len1 = strlen(s);
get_next(s,pext);
for(int i=1;i<=n;i++)
{
int z;//最小循环节
z = i - pext[i];
if(i%z == 0&&i/z>1)
{
printf("%d %d\n",i,i/z);
}
}
printf("\n");
}
}
}