KMP算法

简介: KMP算法

KMP算法

kmp是字符串匹配算法。

主要用途:搜索匹配字符串中的子串p的位置

原理

1 字符串的前缀和后缀

前缀 后缀 最长公共串 最长公共长度
a - - 0
ab a b 0
abc a,ab c,bc 0
abca a ,ab,abc a ,ca,bca a 1
abcab a, ab,abc,abca b, ab ,cab,bcab ab 2
abcabc a,ab, abc,abca,abcab c,bc, abc,cabc,bcabc abc 3

2 搜索匹配值表

搜索词 a b c a b c
匹配值 0 0 0 1 2 3

表是从上面的前缀后缀计算出来的

3 kmp算法流程 a:先求公共最大长度 b:计算出对比数组next

4 例子:

在字符串 BBC ABCDAB ABCDABCDABDE

搜索 ABCDABD

过程:

1 求部分匹配值表

前缀 后缀 最长公共串 最长公共长度
A - - 0
AB A B 0
ABC A,AB C,BC 0
ABCD A,AB,ABC D,CD,BCD 0
ABCDA A,AB,ABC,ABCD A,DA,CDA,BCDA A 1
ABCDAB A, AB ,ABC,ABCD,ABCDA B, AB,DAB,CDAB,BCDAB AB 2
ABCDABD A,AB ,ABC,ABCD,ABCDA,ABCDAB D,BD,ABD,DABD,CDABD,BCDABD 0

2 部分匹配值表

搜索词 A B C D A B D
匹配值 0 0 0 0 1 2 0

3 匹配过程第一步

已知空格与D不匹配时,前面6个字符’ABCDAB’是匹配的。查搜索子串匹配表可知匹配字符B对应的 部分匹配值为2 ,因此按照下面的公式算出向后移动的位数:

移动位数 = 已匹配字符数 - 对应部分匹配值

4 = 6 -2

所以向后移动4位,继续往后移动

匹配过程第二步

因为空格与C不匹配,搜索词继续往后移动;已匹配字符为‘AB’个数为2;C对应部分匹配值为0;则移动2-0 = 2位;

以次匹配直至找到为止

代码实现:

//pattern
//abcabc
//k=0
//q=1
 void make_next(const char *pattern, int *next){
     int q, k;
     int m = strlen(pattern);
     next[0] = 0; //第一位默认0
     for(q = 1, k=0; q < m; q++){
         while( k > 0 &&pattern[q] != pattern[k]) {
             k =  next[k-1];
         }
         if (pattern[q] == pattern[k]) { //前缀和后缀有相同的字符
             k++;
         }
         next[q] = k;
     }
 }
 
 int kmp(const char *text, const char *pattern, int *next) {
        int n = strlen(text);
        int m = strlen(pattern);
        make_next(pattern, next);
        int i, q;
        for(i = 0, q = 0; i<n;i++){
                while(q>0 &&pattern[q] != text[i]){
                        q = next[q-1];
                }
                if (pattern[q] == text[i]){
                        q++;
                }
                if (q == m){
                        break;
                }
        }
        return i-q+1;
 }

测试代码:

int main() {
     char *text = "abcabcabcabcabcd";
    char *pattern = "abcabcd";
    int next[20] = {0};
    int idx = kmp(text, pattern, next);
    printf("match pattern: %d\n", idx);
    return 0;
}

结果:

完整代码:

https://github.com/hengfengyaoren/Sort/blob/main/kmp.c

目录
相关文章
|
4月前
|
算法
数据结构中的KMP算法及其改进算法
KMP算法通过引入部分匹配表,有效避免了重复计算,从而将字符串匹配的时间复杂度降低到O(m+n)。通过进一步优化next数组,KMP算法的效率得到了进一步提升。对于大规模字符串匹配问题,KMP算法及其改进算法提供了高效的解决方案,是计算机科学领域的经典算法之一。
61 3
|
2月前
|
算法 C++
A : DS串应用–KMP算法
这篇文章提供了KMP算法的C++实现,包括计算模式串的next数组和在主串中查找模式串位置的函数,用于演示KMP算法的基本应用。
|
2月前
|
算法
KMP算法
KMP算法
18 0
|
3月前
|
数据采集 算法 JavaScript
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
JavaScript字符串搜索涵盖`indexOf`、`includes`及KMP算法。`indexOf`返回子字符串位置,`includes`检查是否包含子字符串。KMP是高效的搜索算法,尤其适合长模式匹配。示例展示了如何在数据采集(如网页爬虫)中使用这些方法,结合代理IP进行安全搜索。代码示例中,搜索百度新闻结果并检测是否含有特定字符串。学习这些技术能提升编程效率和性能。
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
|
3月前
|
算法 Java
KMP算法详解及其在字符串匹配中的应用
KMP算法详解及其在字符串匹配中的应用
|
4月前
|
人工智能 算法 BI
一篇文章讲明白KMP算法(俗称看毛片算法)
一篇文章讲明白KMP算法(俗称看毛片算法)
41 0
|
4月前
|
算法 Java
Java数据结构与算法:字符串匹配算法之KMP算法
Java数据结构与算法:字符串匹配算法之KMP算法
|
5月前
|
算法 搜索推荐 程序员
第六十三练 字符串匹配 - KMP算法
第六十三练 字符串匹配 - KMP算法
42 2
|
5月前
|
算法
|
5月前
|
存储 自然语言处理 算法
【算法】----BF算法&KMP算法
【算法】----BF算法&KMP算法
46 0