#10044 「一本通 2.2 例 2」Power Strings(KMP)(内附封面)

题目描述

原题来自:POJ 2406

给定若干个长度 \le 10^6 的字符串,询问每个字符串最多是由多少个相同的子字符串重复连接而成的。如:ababab 则最多有 3 个 ab 连接而成。

输入格式

输入若干行,每行有一个字符串。特别的,字符串可能为 . 即一个半角句号,此时输入结束。

样例

输入

abcd
aaaa
ababab
.

输出

1
4
3

数据范围与提示

字符串长度 ≤ 1 0 6 \le 10^6 106

哈希函数做法

大致思路

练KMP,模式串如果第i位与文本串第j位不匹配,就要回到第p[i]位继续与文本串第j位匹配,则模式串第一位到第p[n]与模式串第(n-p[n])位到第n位是匹配的。所以如果n%(n-p[n])==0,则存在重复子串,长度为n-p[n],子串循环了n/(n-p[n])。反之,则没有重复子串,主串自己与自己匹配,输出1。

#include
using namespace std;
const int N=1e8;
int len,p[N],ans;
char a[N];
bool flag=0;
void pre(){
	int j=0;p[1]=0;
	for(int i=1;i<len;i++){
		while(j>0&&a[i+1]!=a[j+1])j=p[j];
		if(a[i+1]==a[j+1])j++;
		p[i+1]=j;
	}
}
int main(){
	while(scanf("%s",a+1)){
		len=strlen(a+1);
		if(a[1]=='.')break;
		pre();
		if(len%(len-p[len])==0){
			cout<<len/(len-p[len])<<endl;
		}
		else cout<<"1"<<endl;
	}
	return 0;
}
/*abcd
aaaa
ababab*/

注:KMP中p数组的初始化实际上就是一个自我匹配的过程,因此在此题中无需加入模板的另一半

附封面

#10044 「一本通 2.2 例 2」Power Strings(KMP)(内附封面)_第1张图片

你可能感兴趣的:(c++,算法,开发语言)