美文网首页
KMP算法概括

KMP算法概括

作者: cheerss | 来源:发表于2020-04-05 19:04 被阅读0次

KMP算法有很多不错的解析,这里推荐两个:12

本文只是做一个简单的概括。

思想

KMP算法的思想用下面一张图就能说清楚:

在上图中,要检测T中是否包含P。

当匹配到某个位置发现两者不相等时(红框),肯定P要继续往后挪。普通的字符串匹配方法(也就是时间复杂度时m*n的那种),一般P只往后挪一个位置(也就是P'),然后从头开始和T比较。但是如图所示,当我们发现红框位置的不一样时,同时也代表P中红框前5个字母已经和T匹配上了,所以只有图中蓝色框部分的字母相同时,P'的比较才有意义,否则P'在前4个字母的比较时候就会匹配失败。

换句话说,当红框位置的匹配失败时,只有b之前的字母有相同的前后缀时,后移后的比较才有意义。再看下图

还是同一个字符串,其中b之前还真有相同的前后缀,也就是“ab”。此时我们可以断言,把P后挪3个位置时安全的,起码对于T中我们已经“看”过的字母,P和它匹配还好。

所以KMP算法的关键就是构建Failure Array(很多博客叫next数组)。next数组的长度和P长度相同,next[j]代表的含义是,在P[:j+1]中,最长的相同的前后缀长度是多少,如下图。next中的2表示P中截止到第5个字母为止的字串中,最长的前后缀是2。(注意,在具体实现时,有的人next的位置和我描述的刚好差1,如上面给的第2个参考文档中的实现)

LeetCode第28题就是实现字符串匹配,代码如下:

class Solution {
public:
    vector<int> generate_next(string s){
        int i = 0, j = 1;
        vector<int> res(s.size(), 0);
        while(j < s.size()){
            if(s[i] == s[j]){
                res[j++] = ++i;
            } else if(i > 0){
                i = res[i-1];
            } else{
                res[j++] = 0;
            }
        }
        return res;
    }
    
    int strStr(string haystack, string needle) {
        vector<int> next = generate_next(needle);
        int i = 0, j = 0;
        while(j < needle.size() && i < haystack.size()){
            if(haystack[i] == needle[j]){
                ++i, ++j;
            } else if(j > 0){
                j = next[j-1];
            } else {
                ++i;
            }
        }
        if(j == needle.size()){
            return i - needle.size();
        } else{
            return -1;
        }
    }
};

假如P的长度是m,T的长度是n,KMP算法的时间复杂度是O(m+n),其中构建next数组复杂度是O(m),匹配复杂度是O(n)。有一个很有趣的证明,以上述的代码为例:

  1. 构建next时,考虑2*j - i的大小,会发现它初始是0,最终最大是2m,且三个if-else分支不论走哪个,2*j-i都是递增的,所以最多训练2m次,也就是O(m).
  2. 匹配时也同理,考虑2*i-j的大小,可以得到同样的结论。

相关文章

  • KMP算法概括

    KMP算法有很多不错的解析,这里推荐两个:1、2 本文只是做一个简单的概括。 思想 KMP算法的思想用下面一张图就...

  • KMP 专题整理

    KMP 学习记录 kuangbin专题十六——KMP KMP 学习总结 朴素 KMP 算法 拓展 KMP 算法(E...

  • 对KMP算法的一些理解

    最近学到KMP算法,下面讲讲对KMP算法的一些个人理解,希望对大家有帮助! 对于KMP算法的理解: 整个KMP算法...

  • AC自动机 图文介绍

    预备知识 Trie(字典树)KMP字符串匹配算法 AC自动机求解问题的类型 一句话概括就是:多模匹配。KMP求解的...

  • KMP算法文章合集

    字符串的查找:朴素查找算法和KMP算法 暴力匹配算法与KMP算法(串的匹配) 字符串查找算法BF和KMP 字符串匹...

  • 串的模式匹配算法

    KMP算法 算法匹配

  • 问答|KMP算法学习笔记

    问题 目录KMP是什么,做什么用的KMP算法的高效体现在哪如何KMP算法的next数组KMP的代码KMP的时间复杂...

  • KMP算法——寻找子串位置

    KMP算法——寻找子串位置 1、KMP算法简介: KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J....

  • 字符串匹配 - KMP算法

    前面我们介绍非常高效的 BM 算法,今天我们介绍另一个非常出名且高效的 KMP 算法。 KMP 算法思想 KMP ...

  • KMP算法及优化

    转载请注明出处: KMP算法及优化 今天看到同学在复习数据结构书上的KMP算法,忽然发觉自己又把KMP算法忘掉了,...

网友评论

      本文标题:KMP算法概括

      本文链接:https://www.haomeiwen.com/subject/wfhpphtx.html