博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

KMP算法

Posted on 2025-04-27 11:11  steve.z  阅读(47)  评论(0)    收藏  举报
// 根据模式串构建 next 数组
void buildNext(const char *pattern, int *next) {
    int i, j;
    int m = (int)strlen(pattern);
    next[0] = -1;
    for (j = 1; j < m; j++) {
        i = next[j - 1];
        while (i >= 0 && (pattern[i + 1] != pattern[j])) {
            i = next[i];
        }
        if (pattern[i + 1] == pattern[j]) {
            next[j] = i + 1;
        } else {
            next[j] = -1;
        }
    }
}

// KMP算法
int KMP(char *text, char *pattern) {
    // 1. 输入检查
    if (text == NULL || pattern == NULL) {
        return -1;
    }
    int N = (int)strlen(text);
    int M = (int)strlen(pattern);
    if (N == 0 || M == 0 || N < M) {
        return -1;
    }

    // 2. 循环判断
    int i = 0, j = 0;
    int *next = (int *)malloc(sizeof(int) * M);
    buildNext(pattern, next);
    // 主串和模式串, 任意一个指针到达末尾的时候, 搜索结束
    while (i < N && j < M) {
        if (text[i] == pattern[j]) {
            i++;
            j++;
        } else if (j > 0) {
            // 1. i 不需要回溯
            // 2. j 的值通过 next函数获取
            j = next[j - 1] + 1;
        } else {
            // 如果 j == 0, 那么 i++ 移动到主串的下一个位置继续匹配
            i++;
        }
    }
    free(next);
    return (j == M) ? (i - M) : -1;
}