算法数据结构 只要行代码,实现快速匹配字符串的KMP算法.docxVIP

算法数据结构 只要行代码,实现快速匹配字符串的KMP算法.docx

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
算法数据结构 | 只需30行代码,实现快速婚配字符串的KMP算法 在计算机领域当中字符串婚配其实是一个非经常见的问题,我们使用它的场景也多到不行计数。比如在一个已经打开的页面当中搜索关键词,再比如说git里面的代码变动的记录,以及论文的查重等等。在这些问题当中有些情况可能还好,比如说我们搜索一个关键词,由于关键词并不长,我们暴力枚举也不会特殊耗时。但是在有些问题当中明显暴力婚配是无法胜任的,比如论文查重。一篇论文动辄上千词,要和库中的上万篇文章进行查重扫描,这当中的工作量可想而知。假如是暴力枚举算法那查重明显会查到天荒地老。 所以晚期的时候字符串婚配是一个难题,既然是难题那么明显就会有很多人来争辩,也因而出了很多成果,很多大牛发表了字符串婚配的算法,其中KMP算法由于效率很高、实现简单度低被应用得最广。到这里,我们就晓得KMP算法是用来字符串婚配的。 比方说我们有两个字符串,A串是:I hate learning English. B串是hate learning,很明显B串是A串的字符串。假如我们暴力枚举来推断的话,我们需要遍历A串当中的每一个起始位置能否能够完成婚配,那么简单度明显是。通过KMP算法,我们可以在的时间内做到这点。 有名的大佬matrix67在KMP算法的引见博客当中有一句有名的骚话,当你有一个宠爱的MM,你可以委婉地问她:“假如你要向你宠爱的人表白的话,我的名字是你的告白语中的子串吗?” Next数组 KMP算法的核心精髓只要一个就是Next数组,但是这个概念并不太简约理解,很多人学KMP放弃就是折戟在了Next这个数组上。 我们先把Next数组是怎样来的放在一边,先来看下Next数组是用来干嘛的,它起作用的原理是什么,最终再来争辩Next数组怎样来的问题。依据我的理解,Next数组其实就是一个中途开头的机会,也就是当我们在枚举婚配的时候,发觉了不婚配的情况,我们不是从头开头,而是从一个最大可能的两头结果开头。 我们来看个例子: 上图中上面的是A串,下面的是B串,我们在婚配的过程当中发觉B串的前面几位都婚配上了,而在最终一位婚配失败。依据常规的做法,我们应当是移动到下一个位置从头开头婚配。但是这是格外铺张的,由于我们观看下可以发觉失败位置的ABC和B串开头的ABC是可以构成婚配的。 我们之前失败的时候推断的是以C结尾的ABCDABC和B串的婚配,在这一次婚配失败之后,我们可以连续尝试婚配其他以C结尾的前缀串,比如ABC。这样我们就可以从两头形态开头,而节省了很多次不必要的枚举。但问题就来了,这个两头结果是怎样来的呢,我们怎样晓得当下失败了上一个可行的两头结果是哪一个? 对,没有错,前面说到的Next数组就是用来存储两头结果的。所以Next可以理解成下一次机会的意思,这样就好理解了。由于我们是在A串当中查找B串,所以这个Next数组应当是针对B的,记录B中每一个位置假如婚配失败,它的前面一个可行的两头形态是哪一个。 我们先写出来B的Next数组,等会再去争辩它是怎样得到的。为了简化编码,我们假设字符串是从1位置开头的,所以我们在0的位置添加一个$符号作为占位符。对于大部分情况都是没有重来的机会的,失败了直接归零。而其中的A和B两个位置是有重来机会的,由于B的前缀当中消灭了A和AB。所以假如在婚配ABD的时候失败了,我们还可以从AB处再次开头尝试婚配ABC。 算法原理 我们想象一根指针指向了B数组当中接下来要婚配的位置,假如婚配失败了,它就会跳转到Next数组当中记录的位置去,婚配成功了我们就向后移动一位。在有了Next数组之后,我们写出代码来真的很简约了: def?kmp(var_str,?template_str): ????#?var_str即A串 ????#?template_str模式串即B串 ????#?我们在两个字符串前加上了占位符 ????var_str?=?$?+?var_str ????template_str?=?$?+?template_str ????next?=?generate_next(template_str) ????n,?m?=?len(var_str),?len(template_str) ????#?head指向要婚配的位置的前一位 ????head?=?0 ????for?i?in?range(1,?n): ????????#?由于next数组很长,可能失败多次 ????????#?直到head+1的位置能婚配上或者head等于0 ????????while?head??0?and?template_str[head+1]?!=?var_str[i]: ????????????head?=?next[head] ???????? ????????#?婚配上了则head

文档评论(0)

duanbingbing + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档