題目 http://poj.org/problem?id=1961
剛開始做這個不知道什麼是kmp演算法 自己看了很多書籍介紹 沒看懂 最後還是看課本知道了一點點
首先我來介紹kmp 演算法吧
next[ j ] 等於 一共分三種情況 1. next [ j ]=0 當 j =1時 ;2. MAX { 1<K< j 且‘p1....p(k-1)'=' p(j-k+1)...p(j-1)'} ;3 next[ j ]=1 其他情況哦;
第一次匹配 當i=3
假設 a b a b c a b c a c b a b
a b c
j=3;
第二次匹配
i=3 -> i=7
a b a b c a b c a c b a b
a b c a c
j=5;
第三次匹配
j=1;
i=7 --->i=11
a b a b c a b c a c b a b
(a)b c a c
j=6;
kmp演算法重點是在於 計算next[ j ]的值哦
下面是計算的next的值
j 1 2 3 4 5 6 7 8
模式串 a b a a b c a c
next[ j ] 0 1 1 2 2 3 1 2
void get_next(char *s1,char *next){ int i=0,j=-1; next[0]=-1; int len=strlen(s1); while(i<len) { if(j==-1||s1[i]==s1[j]) { i++; j++; next[i]=j; } else j=next[j]; }}
現在給出 ac poj1961 的代碼哦
#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define maxn 1000002char s1[maxn];int next[maxn];void get_next(){ int i=0,j=-1; next[0]=-1; int len=strlen(s1); while(i<len) { if(j==-1||s1[i]==s1[j]) { i++; j++; next[i]=j; } else j=next[j]; }}int main(){ int n,test=0,i,len; while(scanf("%d",&n)&&n) { scanf("%s",s1); get_next(); printf("Test case #%d\n",++test); for(i=2;i<=n;i++) //求出前i個字元中重複串 { len=i-next[i]; if(i%len==0&&i/len>1) printf("%d %d\n",i,i/len); } printf("\n"); } return 0;}