kmp算法c语言
时间: 2025-04-20 17:36:27 浏览: 32
KMP (Knuth-Morris-Pratt) 算法是一种高效的字符串匹配算法。它由 Donald Knuth、Vaughan Pratt 和 James H. Morris 同时独立发明,在1977年首次公布。
在传统的暴力搜索方法中,每当模式串和目标文本不匹配时,我们会将模式串回溯到上一步继续比较;而 KMP 则通过预先处理模式串构建部分匹配表(也叫前缀函数),从而可以在发生失配时不回溯指针位置,直接跳过不可能匹配的位置,大大提高了效率。
以下是 C 语言实现的一个简单示例:
```c
#include <stdio.h>
#include <string.h>
void computeLPSArray(char* pat, int M, int* lps);
// 搜索主过程
int KMPSearch(char* pat, char* txt)
{
int M = strlen(pat);
int N = strlen(txt);
// 创建 LPS 数组并初始化为0
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("Found pattern at index %d \n", i - j);
j = lps[j - 1]; // 准备查找下一个匹配项
}
} else { // 当 patt[i]!=txt[j]
if (j != 0){
j = lps[j - 1];// 移动至之前已经匹配的最大长度处,并尝试再次匹配
}else{ // 已经到达模式串开头仍然无法匹配
i++; // 直接向后扫描源串即可
}
}
}
return 0;
}
// 构造临时数组 lps[]
void computeLPSArray(char *pat, int M, int *lps)
{
int length=0; // 最长公共前后缀初始长度设为零
lps[0]=0; // 因为最长真前缀和真后缀都不能为空所以第一项必然是0
int i = 1;
while(i<M){
if(pat[length]==pat[i]){
length++;
lps[i]=length;
i++;
}
else{
if(length!=0){
length=lps[length-1];
}
else{
lps[i]=0;
i++;
}
}
}
}
```
上述程序实现了对给定 `pattern` (即需要寻找的目标子序列)以及对应的较长 `text string` 进行搜索的功能,并输出所有出现过的起始坐标。
请注意:上面这个例子为了简化理解去掉了错误检查和其他一些细节优化工作。实际应用中建议加入更多的健壮性和性能考虑因素进去调整代码逻辑。
阅读全文
相关推荐













