標籤:style color os io 問題 ar line size
對於數組s[0~n-1],計算next[0~n](多計算一位)。
考慮next[n],假設t=n-next[n],如果n%t==0,則t就是問題的解,否則解為1。
這樣考慮:
比如字串"abababab",
a b a b a b a b *
next -1 0 1 2 3 4 5 6 7
考慮這樣的模式比對,將"abababab#"當做主串,"abababab*"當做模式串,於是進行匹配到n(n=8)時,出現了不匹配:
主串 abababab#
模式串 abababab*
於是模式串需要回溯到next[*]=7,這之前的主串和模式串對應相等,於是需要模式串向右滾動的位移是d=n-next[n]=2,即:
123456789
主串 abababab#
模式串 abababab*
於是可以看出,s[0~1]=s[3~4]=s[5~6]=s[7~8]。
所以位移d=n-next[n]可以看作是構成字串s的字串(如果n%d==0,存在這樣的構成),相應的重複次數也就是n/d。
#include <iostream>#include<stdio.h>#include<string.h>using namespace std;int len;int next[1000005];char s[1000005];int kmp_next(){ int i=0,j=-1; next[0]=-1; while(i<len) { if(j==-1||s[i]==s[j]) { i++;j++; next[i]=j; } else j=next[j]; } int x=i-next[i];//碰到不匹配的向前滾動的位移 if(len%x==0) return x; else return len;}int main(){ while(scanf("%s",s)!=EOF) { if(s[0]=='.') break; len=strlen(s); int ans=kmp_next(); ans=len/ans; printf("%d\n",ans); } return 0;}