0x15 字符串

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中的某一次出现 
    }
}

【例题】POJ1961 Period

 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 }  
View Code

最小表示法

    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);

猜你喜欢

转载自www.cnblogs.com/kkkstra/p/11118444.html