kmp & exkmp 模板

不羁岁月 提交于 2019-11-27 10:59:45

kmp

inline void calc_next() { // 计算next数组 a为模式串 从1开始
    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;
    }
}
inline void calc_f() { // kmp b为主串 从1开始
    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) {/* the first time */}
    }
}

 

exkmp

// 求 a 关于 b 的后缀的最长公共前缀, Next 记录 a关于自己每个后缀的最长公共前缀, ret 记录 a 关于 b 的后缀的最长公共前缀
void ExtendedKMP(char *a, char *b, int M, int N, int *Next, int *ret) {
    int i, j, k;
    for (j = 0; 1 + j < M && a[j] == a[1 + j]; ++ j);
    Next[1] = j;
    k = 1;
    for (i = 2; i < M; ++ i) {
        int Len = k + Next[k], L = Next[i - k];
        if (L < Len - i) {
            Next[i] = L;
        } else {
            for (j = max(0, Len - i); i + j < M && a[j] == a[i + j]; ++ j);
            Next[i] = j;
            k = i;
        }
    }
    for (j = 0; j < N && j < M && a[j] == b[j]; ++ j);
    ret[0] = j;
    k = 0;
    for (i = 1; i < N; ++ i) {
        int Len = k + ret[k], L = Next[i - k];
        if (L < Len - i) {
            ret[i] = L;
        } else {
            for (j = max(0, Len - i); j < M && i + j < N && a[j] == b[i + j]; ++ j);
            ret[i] = j;
            k = i;
        }
    }
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!