闲谈KMP算法

今天,习惯性地在Matrix67大神的博客里溜达,每次溜达都能学到好多东西,记得有好几个比较经典的网站都是他的博客上提供的,而每次都有种相见恨晚的感觉。今天无意间看到一篇讲解KMP算法来进行串匹配的文章,链接如下:

KMP详解

    串匹配在通信中应用也是相当广泛,特别是通信中的同步时候,是要进行匹配的,当然具体细节各有不同。KMP算法在Matrix67的博客中已经讲解的非常详细,对于我这种纯菜鸟都能看懂,这就是自己非常欣赏的思维讲解方式,希望大家都能好好品味下~。我写这篇文章的目的就是及时记录自己脑袋里现有的化学反应。

        假设A= ‘1234545945458’,B=‘45458’,我们要来看看它们是否匹配以及在哪匹配?KMP的实现过程是这样的:我们就从A串第一个字符开始扫描,看看它是否与B的第一个字符相等,不相等就继续向后扫描A串。在本例中,A中第四个字符‘4’开始与B串第一个字符‘4’相等。紧接着,貌似我们手气很好,一口气又有‘545’相等,就当我们眼看就要匹配结束即将庆祝的时候,来了个晴天霹雳,垂死病中惊坐起般发现A接下来的字符是‘9’,而不是我们需要的‘8’。这下怎么办呢?接下来就是KMP算法的作用了:到目前为止我们已经匹配了B中的4个字符了,就差最后一个就结束整个匹配了对不,真的就是功亏一篑啊!那么我们前面做的那些都白费了吗?我们当然不能就这样放弃!!

  KMP算法:我们‘一路向北’般的扫描A串,当发现有不匹配的情况出现的时候(例如上面的‘9’和‘8’),马上记录下目前的匹配长度(4),然后,我们就看看刚匹配好的这么长(4)的字符串里,我们能不能做点文章呢?我们尽量还是要保证每次尽可能长的匹配吧?刚才已经匹配了4个字符,现在有一个字符不匹配,不能一下就把我们打回地狱,把匹配长度变为0吧?我们发现4545的结构特征,从后面数的两个字符与从前面数的两个字符正好相等,这意味着什么呢?意义重大啊!!它的意思是我们不再把匹配长度变为0,它保证此时我们匹配的长度为2。再详细讲解如下:

                                                  A = 1 2 34 5 4 5 9 4 5 4 5 8

                                                  B =          4 5 4 5 8                           匹配长度为4,接着扫描A,发现9与8不等。


                                                 A = 1 2 3 4 5 4 5 9 4 5 4 5 8

                                                 B =               4 5 4 5 8                             由于4545的特殊结构,我们保证了此时最大的匹配是2 而不是0.目前还是扫描在9这个位置。


                                                A = 1 2 3 4 5 4 5 9 4 5 4 5 8

                                                B =               4 5 4 5 8                        我们匹配好了2个字符,发现‘9’与‘4’不同,我们看45这个串的结构,它找不到前后相等的子串,我们就只能变成如下结构了(匹配长度回到0),继续扫描A,变为9后的下一个字符‘4’:


                                               A = 1 2 3 4 5 4 5 9 4 5 4 5 8

                                               B =                4 5 4 5 8                      发现它正好与B第一个字符相等,匹配长度从0变为1,接着我们的运气很好,一路下来最后匹配长度等于B的长度时结束匹配。


最后,还是用Matrix67的话总结下吧:扫描字符串A,并更新可以匹配到B的什么位置。当已经匹配好的字符串有特殊结构的时候,我们更新匹配长度时可以不必从0开始(具体从多少开始,这个就是KMP算法里的预处理数组干的事,它就是完成B串的自我匹配,几乎就是KMP算法的翻版!),而当没有特殊结构时就从0开始匹配。再次向67神致敬!!


 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值