判别两棵树是否相等 设计算法_KMP算法

最近朋友面试京东C++研发岗实习生时,被问到KMP算法的实现原理。

KMP算法很多人都会忽略,可能只是听过这个名字罢了,没有真正的学习过,这个算法相对来说比较难理解,今天我参考了很多KMP算法的文章博文,加以优化,撰此博文,分享一下自己的通俗理解。

1、要解决的问题

BF算法、KMP算法要解决的问题相同,即:给出两个字符串A和B,求解A中是否包含B?如果包含,求出包含了几个?

1114a5f0af619bab68eff9e8721b5a7f.png

2、BF算法

针对上面的问题,如果让我们用眼睛找,那么我们大脑使用的就是BF算法,即:一位一位地比较,比较到失配位的时候,将原本指向A串第六个字符的指针

指向第二个字符,指向B串第六个字符的指针
重新指向B串开头,在按照第一遍的方法,再依次比较。

2b861068b0c546d5798bc55c9b9bc2f5.png

69f39eaa382ee75066834822ce6e0631.png

此时要比较的第一位就不相等,即此轮匹配也是必然失败的,但计算机并不知道,它只会按照BF算法一位一位的比较下去(在很多情况下要比较很多位才能发现不匹配),这种暴力求解的算法效率是极低的。

为了让计算机根据已经匹配过的部分知道自己从头匹配的时候应该忽略哪些部分,省去不必要的匹配?(在此例中即为从头跳过第二位的b从第三位开始新的匹配)KMP算法就是用来解决这个问题的。

3、KMP算法

3.1先验概念了解一下

前缀、后缀、公共最大长度next、部分匹配表(Partial Match Table)

abcdef的前缀:a、ab、abc、abcd、abcde(注意:abcdef不是前缀)
abcdef的后缀:f、ef、def、cdef、bcdef(注意:abcdef不是后缀)
abcdef的公共最大长:0(因为其前缀与后缀没有相同的)
ababa的前缀:a、ab、aba、abab
ababa的后缀:a、ba、aba、baba
ababa的公共最大长:3(因为他们的公共前缀后缀中最长的为aba,所以长度为3)
引自: https://www. zhihu.com/question/2192 3021/answer/642165149

部分匹配表:

a75652e3383a6c1027b2170c0464a80a.png
部分匹配表
index行是索引。
字符串B行则记录了所有字符。
next行则记录了当前从B串头部到当前位置的这一子串的公共最大长。
new行记录的值则是(next-1)

3.2步骤

核心:用成功匹配的位数减去匹配值就是下一次要移动的步数。

  1. 字符串A和B从头开始一对一进行比较,直到在index=5处开始不等,在匹配表中找到index=4(一定要找不等处的index-1)时的公共最大长next,此时next=2,
  2. 重新进行第二轮比较的时候可以直接将B串的头部2个字符和A串匹配成功的部分的最后两个字符对齐。然后开始对比B串的第三个字符与A串的失配字符,进行新一轮的匹配。
  3. 关于对齐,我们在匹配时分别用指针
    指向字符串当前匹配的位置,失配之后
    指针
    不变,继续指向A串的失配处,指针
    则指向B串第3个位置(公共最大长的后面一位,索引为公共最大长)

509de5db50574417b30bebe930e4bd31.png
第二轮匹配开始指针指向

黄色的ab即是通过公共最大长直接匹配的位置,红色部分是重新开始匹配的位置(两个指针直接指向的位置),相较于BF算法,我们在这一步跳过了A串的第二个字符“b”,第三个字符“a”,直接将B串头部对齐了第四个字符,并从B串的第三个字符开始重新与此前失配的字符进行新一轮的匹配,这样设计新一轮匹配的过程省去了一大堆不必要的匹配。

public 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值