KMP算法

作者: 王泽强Fantasy | 来源:发表于2017-04-15 22:29 被阅读0次

算法具体思路:

1 求出子串的模式匹配串(pattern)长度,记录在数组 A[i] 中:

如上图记录了每一位的模式匹配串("前缀"和"后缀"的最长的共有元素的长度)的长度。利用动态规划的思想:

从匹配串的概念理解,前缀和后缀的最长的共有元素长度,这说明每一位记录的这个长度就是当前这一位的字符所能匹配到的最长前缀的长度(也就是下一次应该去比较的索引),所以我们可以构造动态方程:

A[0] = 0, A[i] = str.charAt(A[i - 1]) == str.charAt(i) ? A[i - 1] + 1 : str.charAt(i) == str.charAt(0) ? 1 : 0

这样我们可以利用O(m)的时间复杂度构构造出pattern数组 A[i].

2 开始匹配母串,利用pattern 数组避免重复比较:

思想: 设定两个指针, i (母串指针);j(匹配串指针);母串指针 i从头到尾依次扫过(匹配时 ++, 否则不动,当匹配值为0时仍然失配才向后移动一位)。匹配串指针 j 在失配时移动到A[j - 1] 的位置继续匹配。几个问题如下:

(1) 为什么要移动到A[j - 1]:

首先我们来看一下部分匹配值的含义:当我们求匹配值的时候已经用到了这个思想。每一个位置记录的是当前这个字符所能匹配到的最长的前缀长度,也就是下一次应该去比较的地方。所以说明我们失配的时候,要去寻找子串下一次应该去比较的地方,也就是我们求出来的A[j - 1 ]的位置。也就是子串从开头到A[j - 1] - 1的位置已经可以和之前比较过的位置对齐相等。

(2) 这样可以优化多少复杂度:

首先我们看一下之前naive matching的思想:每次不匹配母串的指针需要回退到这次匹配开始的位置加1,子串回到初始位置重新开始新的匹配。也就是说:近似看出母串从m 到 n - m这些位置的字符如果在最坏的情况下(每次都是比较到最后一个发现失配,有点背啊),都要比较m次。而前m个和后m个加起来平均每一位比较了m/2次。 所以复杂度为 O((n - m + 1) * m),随后我们来看一下KMP我们发现就算失配了,我们只是调整子串的指针,而母串的指针只是在原地等待并没有回退(直到匹配了或者匹配值为0仍然失配,这时候才移动);我们还是来看最坏的情况:给出这样的子串 aaaaaa, 母串aaaaabaaaaabaaaaabaaaaaa, 我们发现每次都是匹配到最后一位失配并且母串这一位的母串需要与子串前m - 1个字符都比较一遍发现都不行才会向后移动一位。原因是我们的部分匹配值是一个连续的值(0,1,2,3,4,5). 就算这样复杂度:O(n + (n / m)*(m - 1)) = O(2n)。为n的量级。优化了很多。

3 进一步优化KMP算法:

优化点:对于子串为aaaaa这种情况的优化。

我们发现上面讨论过的KMP算法的最坏的情况有大量的不需要比较的地方,比如由于子串全都是相等的字符,当最后一位失配时我们可以直接将母串的指针向后移动一位同子串第一位重新匹配。所以这是一个可以省略大量不必要的比较的地方。我们对字符全相等的子串的部分匹配值进行研究发现当子串全部字符都相等时会出现A[ j ] = j 的规律,所以当我们失配时可以判断一下A[ j ] == j ?  j = 0, i ++ : j = A[j - 1].这样我们可以避免重复比较,真正实现O(n)的复杂度 。


代码如下图:

转载请著名出处:http://www.jianshu.com/p/07e2c34a07b7

相关文章

  • KMP 专题整理

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

  • 对KMP算法的一些理解

    最近学到KMP算法,下面讲讲对KMP算法的一些个人理解,希望对大家有帮助! 对于KMP算法的理解: 整个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算法(字符串匹配问题)

    一、是什么? 注意,是KMP算法,不是MMP哈,我没有骂人。KMP算法是用来做字符串匹配的,除了KMP算法分,还有...

  • KMP算法

    KMP算法

网友评论

      本文标题:KMP算法

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