KMP(MP)算法详解

Written with StackEdit.
由于CSDN服务器的维护,我迫不得已地用了和CSDN版本相近的StackEdit

KMP 算法,是一种字符串匹配的算法。当然,我们已经学过了一两种字符串匹配算法,先来稍微回顾一下。
首先是暴力匹配,也就是将串中每一个长度等于另一串的子串和另一串进行匹配。若两串的长度为 n m,那么其的时间复杂度显然是 O(nm)
然后是哈希。哈希在本质上是一种概率算法,实际上是采用了一种映射的方法,如果将所有被哈希之前的字串的集合设为 A ,而被哈希之后的字串的哈希值集合设为B,那么也就相当于定义了一个映射 Hash:AB ,注意这不是一个单射,因为在大多数的情况下,有 |A|<|B| 。当然,有很多方法改进,但是只有完美哈希使得它不再算一个概率算法,然而完美哈希本身的操作过于繁琐,一般适用于字串不变的情况,如编译器中的指令。实际上,哈希算法的本质和暴力是一致的,但是由于映射的存在,使得哈希算法要比较的东西就不那么多了,就像暴力算法中只抽样比几位一样,但是哈希算法相当于是在每一位中都抽一点点的样(有些时候不是这样),所以更为准确一些。其的时间复杂度为 Θ(n+mlogvMod) ,其中 v 是计算机所采用的进位制(如现在的一般采用二进制,不排除以后有更高进制的计算机,或者要求相关的交互题:)),Mod则是你所使用的模数(因为我们当时只学了一种哈希:-()。
好吧,回顾完了,我们来稍微了解一些关于 KMP 的东西。 KMP 的本质是暴力匹配的优化,而其有一个较为简单的版本, MP 。本文介绍时将先介绍 MP 算法,再比较 KMP MP 之间那一个 K 的不同。
考虑暴力算法,其思路大致是用指针 i j分别遍历两个串,然后当失配(即两个指针对应的字符不相等时)回到两个串“前面的位置”,也就是像回溯一样不断尝试。
但是,这样单纯地找,有时是不会有好结果的。如下所示,两个串 A B

A:abababc
B:ababc

其中,若在串 A 中找串B,那么第一次尝试匹配到 ababa 时,只有最后一位的 a c 不一样。但是,这时我们注意到,串 B 中有两个ab,所以当回溯时,我们并不用将串 A 中的指针i前移,而只需将 B 中的指针j前移到开头即可。若设 A=a1a2a3a4 B=b1b2b3b4 ,那么因为已经比较,所以自然有 a1=b1,a2=b2,a3=b3,a4=b4 ,于是又由于我们已知 b1=b3,b2=b4 ,那么就有 b1=a3,b2=a4 。所以,只需从原位置继续开始即可。
MP 算法正是基于这样的一种思想。倘若存在某个 [1,j]=[ij,i] ,那么我们定义 j=next(i) ,表示当在 i 位置的字符失配时应当跳到哪里。其的求法我们先不管,但是这样一来匹配就很好写了,代码这里略去,请自行查找资料。
那么,next(i)的求法又应当是怎样的呢?答案是:几乎和匹配一样!想想看, next(i) 的求解,不正相当于是用自己匹配自己吗?假如我们知道 next(i) ,那么我们能找到一个 j ,使得串S中有 Si+1=Sj+1 (当然,有时找不到,这时只需要设为一个特殊值就行了:))那么这样的话,就应当有 next(i+1)=j+1
这,就是 MP 算法的全套,至于 KMP 算法,请自行查阅资料。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
KMP算法(Knuth-Morris-Pratt算法)是一种用于解决字符串匹配问题的高效算法。它的主要思想是利用匹配失败时的信息,尽量减少比较次数,提高匹配效率。 KMP算法的核心是构建一个部分匹配表(Partial Match Table),也称为Next数组。这个表记录了在匹配失败时应该将模式串向右移动的位置。 构建部分匹配表的过程如下: 1. 首先,将模式串中的第一个字符的Next值设为0,表示当匹配失败时,模式串不需要移动; 2. 然后,从模式串的第二个字符开始,依次计算Next值; 3. 当第i个字符与前面某个字符相同的时候,Next[i]的值为该字符之前(不包括该字符)的相同前缀和后缀的最大长度; 4. 如果不存在相同的前缀和后缀,则Next[i]的值为0。 有了部分匹配表之后,KMP算法的匹配过程如下: 1. 用i和j来分别表示模式串和主串的当前位置; 2. 如果模式串中的字符和主串中的字符相同,那么i和j都向右移动一位; 3. 如果模式串中的字符和主串中的字符不同,那么根据部分匹配表来确定模式串的下一个位置; 4. 假设当前模式串的位置为i,根据部分匹配表中的值Next[i],将模式串向右移动Next[i]个位置; 5. 重复上述步骤,直到找到匹配或者主串遍历完毕。 KMP算法的时间复杂度为O(m + n),其中m和n分别是模式串和主串的长度。相比于暴力匹配算法的时间复杂度为O(m * n),KMP算法能够大幅减少比较次数,提高匹配效率。 综上所述,KMP模式匹配算法通过构建部分匹配表并利用匹配失败时的信息,实现了高效的字符串匹配。在实际应用中,KMP算法被广泛地应用于文本编辑、数据搜索和字符串处理等领域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值