KMP算法
next数组的求法
void calc_next() { next[1]=0; for (int i=2, j=0; i<=n; ++i) { while (j>0&&a[i]!=a[j+1]) j=next[j]; if (a[i]==a[j+1]) ++j; next[i]=j; } }
f数组的求法
void calc_next() { for (int i=1, j=0; i<=m; ++i) { while (j>0 && (j==n || b[i]!=a[j+1])) j=next[j]; if (b[i]==a[j+1]) ++j; f[i]=j; //if (f[i]==n) //此时就是A在B中的某一次出现 } }
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 #define next nxt 7 using namespace std; 8 const int INF=0x3f3f3f3f; 9 const int maxn=1000000+10; 10 char a[maxn]; 11 int next[maxn], n, T; 12 13 void calc_next() { 14 next[1]=0; 15 for (int i=2, j=0; i<=n; ++i) { 16 while (j>0&&a[i]!=a[j+1]) j=next[j]; 17 if (a[i]==a[j+1]) ++j; 18 next[i]=j; 19 } 20 } 21 22 int main() { 23 //freopen("a.txt", "r", stdin); 24 //freopen("a.out", "w", stdout); 25 int kase=0; 26 while (cin>>n&&n) { 27 scanf("%s", a+1); 28 calc_next(); 29 printf("Test case #%d\n", ++kase); 30 for (int i=2; i<=n; ++i) { 31 if (i%(i-next[i])==0 && i/(i-next[i])>1) 32 printf("%d %d\n", i, i/(i-next[i])); 33 } 34 printf("\n"); 35 } 36 return 0; 37 }
最小表示法
n=strlen(s+1); for (int i=1; i<=n; ++i) s[n+i]=s[i]; int i=1, j=2, k; while (i<=n&&j<=n) { for (k=0; k<n&&s[i+k]==s[j+k]; ++k); if (k==n) break; if (s[i+k]>s[j+k]) { i=i+k+1; if (i==j) ++i; } else { j=j+k+1; if (i==j) ++j; } } int ans=min(i, j);