KMP算法完整教程

  • 全称: Knuth_Morris_Pratt Algorithm(KMP算法)

  • 类型: 高级检索算法

  • 功能: 字符串匹配查找

  • 提出者: D.E.Knuth(克努兹),J.H.Morris(莫瑞斯),V.R.Pratt(普莱特)

  • 所属领域: 数据结构学

  • 应用场景: 统计软件

  • 时间复杂度: O(m+n)

一。原始匹配字符串方法

    以前,我们要肉眼在一个长字符串中寻找一个关键字词,比如在word文档中找一个单词,我们的世界观决定的方法论就是穷举法:挨个搜寻单词的第一个字母,每找到一个就定位然后匹配下一个字母,当匹配错误时就会放弃之前的匹配,沿着刚才的进度继续搜索首字母.

   这种方法也叫作”暴力字符匹配”,和早期计算机检索算法共享着同样的思想,其中被检索的字符串数据库叫做”主串”,检索的字符串叫”模式串”.名字很怪异我也没办法.

    于是依照这种算法我们可以编写一个程序来实现它:
int Index(SString S,SString T,int pos)

{

  i=pos;j=1;

  while(i<=S[0]&&j<=T[0])

  {

    if(S[i]==T[j]){++i;++j;}

    else{i=i-j+2;j=1;}//主串指针回溯重新开始下一趟匹配.

  }

  if(j>T[0])return i-T[0];

  else return 0;

}

//返回模式串T在主串S第pos之后部分中的位置,若不存在则函数值为0.

这里要注意i和j的指针回溯问题,注意细节,具体如下图:



然后问题就来了,这种算法在特定的情况下暴露出一些问题,在时间效率上不是很完美,因为它毕竟是一种穷举法,也符合人们的第一感觉,但是并不是最优的解决方案。比如说当在模式串中比较到第5个字符时才发现不匹配,那么之前四个字符都完全匹配,下一步就不需要再把模式串一位一位的向后移,而很可能直接把模式串向后移动四位就可以了,省去了三次比较,比如模式串是“aceddfaa”,主串是“acedabcd”的情况。

二。初代KMP算法

   针对上面那个例子,我们可以展开思考,如果模式串匹配到第j个字符不匹配的话,接下来只需要在主串中这个位置从模式串中第f(j)的字符开始比较就行了,而不需要从第一个开始。而且f(j)只与模式串中第j个字符以前的所有字符有关。好了,这个f(j)我们用一个数组来存放,就是next【j】。求出next【j】就是KMP算法的核心。可以看出next【j】的值越小越好,优化的效率越高。

KMP的next数组求法是很不容易搞清楚的一部分,也是最重要的一部分。我这篇文章就以我自己的感悟来慢慢推导一下吧!保证你看完过后是知其然,也知其所以然。

如果你还不知道KMP是什么,请先阅读上面的链接,先搞懂KMP是要干什么。

下面我们就来说说KMP的next数组求法。

KMP的next数组简单来说,假设有两个字符串,一个是待匹配的字符串strText,一个是要查找的关键字strKey。现在我们要在strText中去查找是否包含strKey,用i来表示strText遍历到了哪个字符,用j来表示strKey匹配到了哪个字符。

如果是暴力的查找方法,当strText[i]和strKey[j]匹配失败的时候,i和j都要回退,然后从i-j的下一个字符开始重新匹配。

而KMP就是保证i永远不回退,只回退j来使得匹配效率有所提升。它用的方法就是利用strKey在失配的j为之前的成功匹配的子串的特征来寻找j应该回退的位置。而这个子串的特征就是前后缀的相同程度。

所以next数组其实就是查找strKey中每一位前面的子串的前后缀有多少位匹配,从而决定j失配时应该回退到哪个位置。

我知道上面那段废话很难懂,下面我们看一个彩图:



这个图画的就是strKey这个要查找的关键字字符串。假设我们有一个空的next数组,我们的工作就是要在这个next数组中填值。

KMP算法完整教程 (上)的更多相关文章

  1. 【★】KMP算法完整教程

    KMP算法完整教程 全称:                               Knuth_Morris_Pratt Algorithm(KMP算法) 类型:                 ...

  2. 【★】KMP算法完整教程

    KMP算法完整教程 全称:                               Knuth_Morris_Pratt Algorithm(KMP算法) 类型:                 ...

  3. !KMP算法完整教程

      KMP算法完整教程 全称:                               Knuth_Morris_Pratt Algorithm(KMP算法) 类型:                ...

  4. KMP算法完整教程 (下)

    下面我们用数学归纳法来解决这个填值的问题. 这里我们借鉴数学归纳法的三个步骤(或者说是动态规划?): 1.初始状态 2.假设第j位以及第j位之前的我们都填完了 3.推论第j+1位该怎么填 初始状态我们 ...

  5. kmp算法简明教程

    在字符串s中寻找模式串p的位置,这是一个字符串匹配问题. 举例说明: i = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 s = a b a a c a b a a a b a a ...

  6. KMP算法具体解释(转)

    作者:July. 出处:http://blog.csdn.net/v_JULY_v/. 引记 此前一天,一位MS的朋友邀我一起去与他讨论高速排序,红黑树,字典树,B树.后缀树,包含KMP算法,只有在解 ...

  7. KMP算法(研究总结,字符串)

    KMP算法(研究总结,字符串) 前段时间学习KMP算法,感觉有些复杂,不过好歹是弄懂啦,简单地记录一下,方便以后自己回忆. 引入 首先我们来看一个例子,现在有两个字符串A和B,问你在A中是否有B,有几 ...

  8. 数据结构20:KMP算法(快速模式匹配算法)详解

    通过上一节的介绍,学习了串的普通模式匹配算法,大体思路是:模式串从主串的第一个字符开始匹配,每匹配失败,主串中记录匹配进度的指针 i 都要进行 i-j+1 的回退操作(这个过程称为“指针回溯”),同时 ...

  9. KMP算法具体解释

    这几天学习kmp算法,解决字符串的匹配问题.開始的时候都是用到BF算法,(BF(Brute Force)算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配 ...

随机推荐

  1. angularjs中ng-show的使用

    ng-show 指令在表达式为 true 时显示指定的 HTML 元素,否则隐藏指定的 HTML 元素.下面是示例: <!doctype html> <html lang=" ...

  2. onvif杂项

    onvif规范 中文介绍 什么是ONVIF ? ONVIF规范描述了网络视频的模型.接口.数据类型以及数据交互的模式.并复用了一些现有的标准,如WS系列标准等.ONVIF规范的目标是实现一个网络视频框 ...

  3. [Python]datetime常用的几个操作

    #coding: utf-8 ''' 日期相关的操作 ''' from datetime import datetime from datetime import timedelta DATE_FMT ...

  4. DBA眼中的CLR

    SQL Server 2005引入CLR之後,開發者們熱情地接受了它. CLR作爲一個強有力的工具,開發者可在數據庫中利用它調用其它面嚮對象語言編寫而成的功能. 從DBA的視角來看,CLR的引入淡化了 ...

  5. GO!自制一款【不丑】的名片

    大概每一个人都有自己的名片.也见过不少名片. 我敢打赌,你常常认为很多名片"不咋地".尽管不是全部人都具备一定的审美眼光,但实际上每一个人都具备较高的"审丑"眼 ...

  6. 算法笔记_012:埃拉托色尼筛选法(Java)

    1 问题描述 Compute the Greatest Common Divisor of Two Integers using Sieve of Eratosthenes. 翻译:使用埃拉托色尼筛选 ...

  7. Linux mkdir 如何递归创建目录?

    mkdir 如何递归创建目录? mkdir –vp 目录1/目录2/目录3   详细介绍: linux mkdir 命令用来创建指定的名称的目录,要求创建目录的用户在当前目录中具有写权限,并且指定的目 ...

  8. 桥(Bridge)模式

    Bridge定义:将抽象和行为划分开来,各自独立,但能动态的结合. 为什么使用桥模式 通常,当一个抽象类或接口有多个具体实现(concrete subclass),这些concrete之间关系可能有以 ...

  9. [转发]在Visual Studio 2010/2012/2013/2015上使用C#开发Android/IOS安装包和操作步骤

    官方学习文档:http://developer.xamarin.com/guides/android/getting_started/ 官方学习例子:http://developer.xamarin. ...

  10. js&jquery 获取select下拉框的值、文本内容、自定义属性

      js&jquery 获取select下拉框的值.文本内容.自定义属性 CreationTime--2018年7月2日09点22分 Author:Marydon html <selec ...