KMP算法-C语言实现

KMP完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int* build_prefix_table(const char* str_pat, int len_pat) {
    int* prefix_table = (int*)calloc(1, sizeof(int) * len_pat);
    int* tmp_table = (int*)calloc(1, sizeof(int) * len_pat);
    if (NULL == prefix_table || NULL == tmp_table) {
        perror("calloc()");
        exit(1);
    }

    int i = 0, j = 1;
    tmp_table[0] = 0;
    while (j < len_pat) {        // O(len_pat)
        if (i == 0 && str_pat[i] != str_pat[j]) {
            tmp_table[j] = 0;
            j++;
        }
        else if (str_pat[i] == str_pat[j]) {
            tmp_table[j] = i + 1;
            i++;
            j++;
        }
        else {
            i = tmp_table[i - 1];
        }
    }
    
    printf("prefix table: ");
    for(int i = 0; i < len_pat; i++)
        printf("%d ", tmp_table[i]);

    // 把tmp_table抄录到prefix_table, 注意首项值为-1
    prefix_table[0] = -1;
    for (int i = 1; i < len_pat; i++)   // O(len_pat)
        prefix_table[i] = tmp_table[i - 1];

    free(tmp_table);
    return prefix_table;
}

int KMP(const char* str, const char* pat) {
    int len_str = strlen(str);      // O(len_str)
    int len_pat = strlen(pat);      // O(len_pat)
    if (len_pat > len_str) {
        fprintf(stderr, "len_pat > len_str\n");
        return -1;
    }

    int i_str = 0, i_pat = 0;
    int* prefix_table = build_prefix_table(pat, len_pat);    // Tm = O(?)
    while (i_str < len_str && i_pat < len_pat) {             // O(len_pat)
        if (str[i_str] == pat[i_pat]) {
            i_str++;
            i_pat++;
        }
        else if (str[i_str] != pat[i_pat] &&
            prefix_table[i_pat] != -1) {
            i_pat = prefix_table[i_pat];
        }
        else {
            i_str++;
        }
    }
    
    if (i_pat == len_pat)
        return i_str - len_pat;
    return -1;
}

int main() {
    char string[] = { "abaacababcac" };
    char pattern[] = { "abab" };

    int pos = KMP(string, pattern);
    if (-1 == pos)
        printf("Not Found!\n");
    else {
        printf("\nposition in string: %d\n", pos);
        printf("%s\n", string + pos);
    }

    return 0;
}

运行结果:

KMP算法-C语言实现KMP算法-C语言实现

参考资料


上一篇:vscode----vue模板--用户代码片段--快捷


下一篇:LeetCode题解(1292):元素和小于等于阈值的正方形的最大边长(Python)