找字符串的最短循环节

 

 1. kmp

#include <bits/stdc++.h>
using namespace std ; 
const int N=1e6+1;
 char a[N];
 int n,p[N];
 
 void init(){
 	 int i,j=0;
 	 
 	 for(i=1;i<n;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(cin>>a+1,a[1]!='.'){
 		n=strlen(a+1);
 		init();
 		if(n%(n-p[n])) cout<<1<<endl;
 		else  cout<<n/(n-p[n])<<endl;
	}
 }

2. Hash

 

#include<iostream>
#include <algorithm>
#include <cstring>
using namespace std;
 #define int long long
  const int N=1e6+5;
  
 char a[N];
 int n;
 int h[N],pow[N];
 int bas=29;
 
 int f2(int l,int r){
     return h[r]-h[l-1]*pow[r-l+1];
 }
 void solve(){
 		for(int i=1;i<=n;i++){
 			if(n%i==0&&f2(i+1,n)==f2(1,n-i)){
 				cout<<n/i<<endl;return;
 			}
 		}
 		cout<<1<<endl;	
 }
 signed main(){
 	pow[0]=1;
 	for(int i=1;i<=1e6;i++) pow[i]=bas*pow[i-1];
 	while(cin>>a+1,a[1]!='.'){
 		n=strlen(a+1);
 		for(int i=1;i<=n;i++) h[i]=h[i-1]*bas+a[i];
 		
 		solve();
 	}
 }
 
 

 

posted on 2022-10-25 13:47  towboat  阅读(27)  评论(0)    收藏  举报