返回

KMP 算法 C 语言实现详解:深入理解字符串模式匹配

人工智能

KMP 算法 C 语言实现详解

摘要

本文旨在深入剖析 KMP 算法的 C 语言实现,揭示其在模式匹配中的强大功效。通过深入理解算法的原理、实现细节和应用实例,读者将掌握 KMP 算法的精髓。

引言

KMP 算法(又称 Knuth-Morris-Pratt 算法)是一种高效的字符串模式匹配算法,广泛用于文本处理、生物信息学和其他领域。它由 Donald Knuth、James Morris 和 Vaughan Pratt 于 1977 年提出,以其卓越的性能和广泛的应用著称。

算法原理

KMP 算法的核心思想在于利用部分匹配表(PMT)来避免冗余比较。PMT 是一个长度为模式串长度的数组,其中每个元素表示模式串中对应字符的失效函数值。失效函数值定义为模式串中该字符及其前缀串的最大匹配长度。

在匹配过程中,算法使用 PMT 优化匹配步骤。当比较模式串的当前字符与目标串的当前字符不匹配时,算法不会从头开始比较,而是根据 PMT 跳转到模式串中匹配位置最靠前的前缀串的下一个字符,从而节省比较次数。

C 语言实现

以下是用 C 语言实现的 KMP 算法:

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

// 计算失配函数
void computeLPSArray(char *pat, int M, int *lps) {
    int len = 0;
    lps[0] = 0;

    i = 1;
    while (i < M) {
        if (pat[i] == pat[len]) {
            len++;
            lps[i] = len;
            i++;
        } else {
            if (len != 0) {
                len = lps[len - 1];
            } else {
                lps[i] = 0;
                i++;
            }
        }
    }
}

// KMP 算法
void KMP(char *txt, char *pat) {
    int M = strlen(pat);
    int N = strlen(txt);

    int lps[M];

    // 计算失配函数
    computeLPSArray(pat, M, lps);

    int i = 0;  // txt 指针
    int j = 0;  // pat 指针

    while (i < N) {
        if (pat[j] == txt[i]) {
            j++;
            i++;

            if (j == M) {
                printf("模式串在目标串中出现的位置:%d\n", i - j);
                j = lps[j - 1];
            }
        } else {
            if (j != 0) {
                j = lps[j - 1];
            } else {
                i++;
            }
        }
    }
}

int main() {
    char txt[] = "ABABDABACDABABCABAB";
    char pat[] = "ABABCABAB";

    KMP(txt, pat);

    return 0;
}

应用实例

以下是一个应用 KMP 算法的实例,展示如何在一个目标串中查找一个模式串:

目标串: ABABDABACDABABCABAB
模式串: ABABCABAB

匹配结果:
模式串在目标串中出现的位置:10

性能分析

KMP 算法的时间复杂度为 O(m + n),其中 m 和 n 分别是模式串和目标串的长度。与朴素算法 O(mn) 的时间复杂度相比,KMP 算法具有显著的优势,尤其是在模式串较长的情况下。

优点和局限性

优点:

  • 高效:与朴素算法相比,时间复杂度更低。
  • 鲁棒性:在各种应用场景中表现出色。
  • 简单易懂:算法原理清晰,易于理解和实现。

局限性:

  • 依赖模式串:算法的性能受模式串长度的影响。
  • 存储开销:需要额外存储空间来计算 PMT。

总结

KMP 算法是一种高效、鲁棒且易于理解的字符串模式匹配算法。其 C 语言实现充分展现了算法的强大功能,在文本处理和数据科学等领域具有广泛的应用。掌握 KMP 算法是程序员必备的技能,它可以大大提高字符串处理任务的效率。

延伸阅读