kmp算法使用方法.docx

  1. 1、本文档共23页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
KMP 算法(Knuth-Morris-Pratt 算法)是一个著名的字符串匹配算法,效率很高,但是确实有点复杂。 有一些优秀的同学通过手推 KMP 算法的过程来辅助理解该算法,这是一种办法,不过本文要从逻辑层面帮助读者理解算法的原理。十行代码之间,KMP 灰飞烟灭。 先在开头约定,本文用?pat?表示模式串,长度为?M,txt?表示文本串,长度为?N。KMP 算法是在?txt?中查找子串?pat,如果存在,返回这个子串的起始索引,否则返回 -1。 为什么我认为 KMP 算法就是个动态规划问题呢,等会再解释。对于动态规划,之前多次强调了要明确?dp?数组的含义,而且同一个问题可能有不止一种定义?dp?数组含义的方法,不同的定义会有不同的解法。 读者见过的 KMP 算法应该是,一波诡异的操作处理?pat?后形成一个一维的数组?next,然后根据这个数组经过又一波复杂操作去匹配?txt。时间复杂度 O(N),空间复杂度 O(M)。其实它这个?next?数组就相当于?dp?数组,其中元素的含义跟?pat?的前缀和后缀有关,判定规则比较复杂,不好理解。本文则用一个二维的?dp?数组(但空间复杂度还是 O(M)),重新定义其中元素的含义,使得代码长度大大减少,可解释性大大提高。 PS:本文的代码参考《算法4》,原代码使用的数组名称是?dfa(确定有限状态机),因为我们的公众号之前有一系列动态规划的文章,就不说这么高大上的名词了,我对书中代码进行了一点修改,并沿用?dp?数组的名称。 一、KMP 算法概述 首先还是简单介绍一下 KMP 算法和暴力匹配算法的不同在哪里,难点在哪里,和动态规划有啥关系。 暴力的字符串匹配算法很容易写,看一下它的运行逻辑: // 暴力匹配(伪码) int search(String pat, String txt) { int M = pat.length; int N = txt.length; for (int i = 0; i <= N - M; i++) { int j; for (j = 0; j < M; j++) { if (pat[j] != txt[i+j]) break; } // pat 全都匹配了 if (j == M) return i; } // txt 中不存在 pat 子串 return -1; } 对于暴力算法,如果出现不匹配字符,同时回退?txt?和?pat?的指针,嵌套 for 循环,时间复杂度?O(MN),空间复杂度O(1)。最主要的问题是,如果字符串中重复的字符比较多,该算法就显得很蠢。 比如 txt = "aaacaaab" pat = "aaab": 很明显,pat?中根本没有字符 c,根本没必要回退指针?i,暴力解法明显多做了很多不必要的操作。 KMP 算法的不同之处在于,它会花费空间来记录一些信息,在上述情况中就会显得很聪明: 再比如类似的 txt = "aaaaaaab" pat = "aaab",暴力解法还会和上面那个例子一样蠢蠢地回退指针?i,而 KMP 算法又会耍聪明: 因为 KMP 算法知道字符 b 之前的字符 a 都是匹配的,所以每次只需要比较字符 b 是否被匹配就行了。 KMP 算法永不回退?txt?的指针?i,不走回头路(不会重复扫描?txt),而是借助?dp?数组中储存的信息把?pat?移到正确的位置继续匹配,时间复杂度只需 O(N),用空间换时间,所以我认为它是一种动态规划算法。 KMP 算法的难点在于,如何计算?dp?数组中的信息?如何根据这些信息正确地移动?pat?的指针?这个就需要确定有限状态自动机来辅助了,别怕这种高大上的文学词汇,其实和动态规划的?dp?数组如出一辙,等你学会了也可以拿这个词去吓唬别人。 还有一点需要明确的是:计算这个?dp?数组,只和?pat?串有关。意思是说,只要给我个?pat,我就能通过这个模式串计算出?dp?数组,然后你可以给我不同的?txt,我都不怕,利用这个?dp?数组我都能在 O(N) 时间完成字符串匹配。 PS:我认真写了 100 多篇原创,手把手刷 200 道力扣题目,全部发布在? labuladong的算法小抄,持续更新。建议收藏,按照我的文章顺序刷题,掌握各种算法套路后投再入题海就如鱼得水了。 具体来说,比如上文举的两个例子: txt1 = "aaacaaab" pat = "aaab" txt2 = "aaaaaaab" pat = "aaab" 我们的?txt?不同,但是?pat?是一样的,所以 KMP

您可能关注的文档

文档评论(0)

xx_zk + 关注
实名认证
内容提供者

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

1亿VIP精品文档

相关文档