欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > kmp算法

kmp算法

2025/4/3 7:16:04 来源:https://blog.csdn.net/weixin_41554427/article/details/146717879  浏览:    关键词:kmp算法

kmp算法C语言实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 构建部分匹配表(next数组)
void computeLPSArray(const char *pattern, int pattern_len, int *lps) {int length = 0;  // 当前最长公共前后缀长度lps[0] = 0;     // 首字符无前缀,直接置0int i = 1;while (i < pattern_len) {if (pattern[i] == pattern[length]) {length++;lps[i] = length;i++;} else {if (length != 0) {// 回退到前一个最长匹配位置length = lps[length - 1];} else {// 无法进一步回退,当前lps为0lps[i] = 0;i++;}}}
}// KMP搜索算法
int KMPSearch(const char *text, const char *pattern) {int text_len = strlen(text);int pattern_len = strlen(pattern);if (pattern_len == 0) return 0;  // 空模式直接匹配int *lps = (int*)malloc(pattern_len * sizeof(int));computeLPSArray(pattern, pattern_len, lps);int i = 0;  // text索引int j = 0;  // pattern索引while (i < text_len) {if (pattern[j] == text[i]) {i++;j++;}// 找到完全匹配if (j == pattern_len) {free(lps);return i - j;  // 返回匹配起始位置}// 失配且j未到开头else if (i < text_len && pattern[j] != text[i]) {if (j != 0) {j = lps[j - 1];  // 根据lps表回退} else {i++;  // 无法回退,移动text指针}}}free(lps);return -1;  // 未找到匹配
}int main() {const char *text = "ABABDABACDABABCABAB";const char *pattern = "ABABCABAB";int result = KMPSearch(text, pattern);if (result != -1) {printf("Pattern found at index: %d\n", result);} else {printf("Pattern not found\n");}return 0;
}

代码说明:

  1. 核心思想

    • 通过预处理模式字符串生成部分匹配表(LPS数组),记录每个位置的最长公共前后缀长度

    • 匹配失败时利用LPS数组避免回溯主字符串

  2. computeLPSArray函数

    • 时间复杂度:O(M),M为模式串长度

    • 使用双指针技术构建LPS数组

    • 处理三种情况:字符匹配、字符不匹配但有公共前缀、字符不匹配且无公共前缀

  3. KMPSearch函数

    • 时间复杂度:O(N),N为主串长度

    • 双指针遍历主串和模式串

    • 通过LPS数组实现高效回退

  4. 优势

    • 相比暴力匹配的O(MN)时间复杂度,优化为O(M+N)

    • 适合处理大量重复模式串的场景

    • 特别适合流式数据匹配(不需要存储整个主串)

示例输出:

Pattern found at index: 10

可以通过修改main函数中的text和pattern变量来测试不同输入。算法正确处理以下情况:

  • 模式串出现在开头/中间/末尾

  • 存在多个候选匹配

  • 模式串包含重复子串

  • 完全失配的情况

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com