程序员必会算法-KMP算法
KMP算法是一种优秀的字符串匹配算法,字符串匹配的常规算法是一步一步进行移位和比较操作,直至找到完全相匹配的字符串。
下面通过一个例子,为大家仔细说明KMP算法的使用和思路:
问题:
在字符串“DEABCDABABCDABCDABDE”字符串中,匹配字符串"ABCDABD".
算法思路:
KMP算法的思路在于,根据已经匹配的部分字符的信息,不把搜索位置移回已经比较过的位置,这样就提高了效率,是不是还是有点不清楚?没关系,让我们来根据一个例子来切实体会一下KMP算法是如何实现的。
图解:
1、KMP算法的核心是一张“部分匹配表”,这个表是怎么来的,后面再说,先用了再说,下图就是该问题的部分匹配表。

这个表上面一行是我们的模式字符串,下面一行是每个字符所对应的匹配值
移位规则是 移动位数 = 已匹配的字符串长度 - 已匹配字符串的最后一位字符所对应的匹配值。
2、接下来就开始进行操作

上图中我们看到,移位两位后,我们找到了部分匹配的字符串"ABCDAB",但并没有找到完全匹配的字符串,如果是常规思路,就是在继续往下一步一步移位,但我们这里不这样进行,我们观察到,已经匹配的字符串长度是6,匹配到的最后一个字符是"B",查询部分匹配表,这个“B”的部分匹配值是2,那么根据我们算法的移位规则,下一步我们的移位长度 = 6 - 2 = 4;
3、

╮(╯▽╰)╭,有没有发现,移了4位之后,刚好到达了下一个“AB”处?是不是很神奇?好了,打住,我们继续往下移,当前已匹配的字符串长度为2,查询这个“B”的匹配值为0(别和上个B搞混了),根据算法,我们接下来移位长度是 2 - 0 = 2;
4、

继续,和前面的步骤相同,我们这次移位长度为 6 - 2 = 4;
5、

至此,我们已经找到了完全匹配的字符串,当然,如果母字符串的长度较长,我们可以继续进行移位,继续寻找,和之前的步骤相同,下次我们移位长度为 7 - 0 = 7。
算法分析:
不知道大家看到现在,有没有一点明悟?来,让我们分析一下模式字符串“ABCDABD”:
对于搜索来说,我们首先关注的肯定是第一个字符,如果第一个字符都不匹配,那么后面的字符就没有比较的必要了,该目标字符串的第一个字符是’A‘,让我们看看这个字符串里有没有’A‘,诶,还真有,假如说我们现在已经匹配了“ABCDA”,5个字符,我们要移4位才能从第一个'A'移到第二个'A',’A‘只有一个字符,5 - 1 = 4;
再往下看,关注完第一个字符,我们开始关注和第一个字符依次相连的子字符串,这些字符串有一个共性,就是第一个字符都是’A‘,那我们看看这种字符串能有多少,"AB","ABC","ABCD","ABCDA","ABCDAB","ABCDABD",再看看这些字符串在目标字符串“ABCDABD”中存在几个,可以看出,除去和第一个“A”相连的,“AB”还有一个,其余的没有,而"AB"长度为2,所以在表中,第二个B的匹配值为2。
该算法的核心思路在于,有时候,字符串的头部和尾部可能会有重复。
不知道大家有没有听懂?让我们把匹配字符串换一下,换成“ABCDABC”,现在的部分匹配表应该是:

算法思考和延伸:
如果模式字符串过长,部分匹配表的生成会占用较多的时间,如何去提高部分匹配表的生成效率,是该算法的优化所在。(个人观点,如有大佬,请指教!)
该算法思想和字典编码有一定的相通之处。改天我会写出一个字典编码的文章。敬请期待!
程序员必会算法-KMP算法的更多相关文章
- c++程序员必知的几个库
c++程序员必知的几个库 1.C++各大有名库的介绍——C++标准库 2.C++各大有名库的介绍——准标准库Boost 3.C++各大有名库的介绍——GUI 4.C++各大有名库的介绍——网络通信 5 ...
- 迈向高阶:优秀Android程序员必知必会的网络基础
1.前言 网络通信一直是Android项目里比较重要的一个模块,Android开源项目上出现过很多优秀的网络框架,从一开始只是一些对HttpClient和HttpUrlConnection简易封装使用 ...
- 程序员必知的8大排序(三)-------冒泡排序,快速排序(java实现)
程序员必知的8大排序(一)-------直接插入排序,希尔排序(java实现) 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现) 程序员必知的8大排序(三)-------冒 ...
- 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现)
程序员必知的8大排序(一)-------直接插入排序,希尔排序(java实现) 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现) 程序员必知的8大排序(三)-------冒 ...
- 程序员必知的8大排序(一)-------直接插入排序,希尔排序(java实现)
http://blog.csdn.net/pzhtpf/article/details/7559896 程序员必知的8大排序(一)-------直接插入排序,希尔排序(java实现) 程序员必知的8大 ...
- 值得花费一周研究的算法 -- KMP算法(indexOf)
KMP算法是由三个科学家(kmp分别是他们名字的首字母)创造出来的一种字符串匹配算法. 所解决的问题: 求文本字符串text内寻找第一次出现字符串s的下标,若未出现返回-1. 例如 text : &q ...
- [置顶] 程序员必知(三):一分钟知道URI编码(encodeURI)
因为浏览器会用一些特殊的字符作为特定的意义,所以在要传输的内容上如果有这些特殊的字符的话,就需要对其进行转义才能正确传输,如以下字符为发送时候的关键字,即特殊字符 ;/?:@&=+$,# 所以 ...
- 数据结构与算法--KMP算法查找子字符串
数据结构与算法--KMP算法查找子字符串 部分内容和图片来自这三篇文章: 这篇文章.这篇文章.还有这篇他们写得非常棒.结合他们的解释和自己的理解,完成了本文. 上一节介绍了暴力法查找子字符串,同时也发 ...
- Android程序员必知必会的网络通信传输层协议——UDP和TCP
1.点评 互联网发展至今已经高度发达,而对于互联网应用(尤其即时通讯技术这一块)的开发者来说,网络编程是基础中的基础,只有更好地理解相关基础知识,对于应用层的开发才能做到游刃有余. 对于Android ...
- 程序员必知的8大排序(四)-------归并排序,基数排序(java实现)
程序员必知的8大排序(一)-------直接插入排序,希尔排序(java实现) 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现) 程序员必知的8大排序(三)-------冒 ...
随机推荐
- Dell3470无法开机或开机黑屏情况下检测屏幕是否正常
故障现象:Dell3470无法开机,点击开关按键无任何反应 故障分析:释放静电后故障依旧.更换电源适配器后故障依旧,初判主板故障,无法确认屏是否正常 解决方法:除去拆机单独测试外,Dell售后告知一个 ...
- KVO的使用二:常用方法及小技巧
(文章及代码接上一篇) options详解: KVO的注册方法中有一个options枚举,用来确定观察者的接收消息方法接收的信息,那么具体有什么关联呢?下面通过一段代码来验证是如何关联的.依次选择op ...
- hadoop过程中遇到的错误与解决方法
本文整理了在hadoop学习过程中遇到的各种问题. windows下开发环境搭建 大部分情况下,我们都是在windows下开发,hadoop则一般部署于linux服务器(无论是CDH还是原生hadoo ...
- 面向复杂应用,Node.js中的IoC容器 -- Rockerjs/core
Rockerjs Core 项目地址 项目主页 基于 TypeScript 和注解的轻量级IoC容器,提供了依赖注入.面向切面编程及异常处理等功能.Rockerjs Core可在任意工程中引入,是一个 ...
- Hello2 source analysis
在example目录下的web\servlet\hello2\src\main\java\javaeetutorial\hello2路径里可以找到hello2的GreetingServlet.java ...
- Dockerfile详解及优化
Dockerfile详解 0. Dockerfile的作用 docker可以根据Dockerfile中的指令来构建docker镜像.Dockerfile是一个文本文件,其应当包含用户想要构建一个镜像的 ...
- .NET Core Agent
.NET Core Agent 熟悉java的朋友肯定知道java agent,当我看到java agent时我很是羡慕,我当时就想.net是否也有类似的功能,于是就搜索各种资料,结果让人很失望.当时 ...
- Maven pom详解
POM全称是Project Object Model,即项目对象模型.pom.xml是maven的项目描述文件,以xml的 形式描述项目的信息,包括项目名称.版本.项目id.项目的依赖关系.编译环境. ...
- VUE之图表操作
参考 v-charts文档有详细说明,不多做介绍. 感谢博主的梳理,我在此基础之上稍作修改 效果展示: 在工作中遇到了就记录下来,留作备用,以便今后查阅: 安装 npm install vue-sch ...
- Java问题解决:"错误: 找不到或无法加载主类"
参考资料:https://www.cnblogs.com/wangxiaoha/p/6293340.html 场景: 使用java命令运行.class文件时出现:“错误: 找不到或无法加载主类”: 解 ...