Python ---- KMP(博文推荐+代码)
既解决完后宫问题(八皇后问题)后,又利用半天的时间完成了著名的“看毛片”算法——KMP。对于初学者来说这绝对是个大坑,非常难以理解。
在此,向提出KMP算法的三位大佬表示诚挚的敬意。!!!牛X!!!
首先,先介绍一下什么是KMP算法:KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。[1]
In a word: !!!敲黑板!!!, 在进行字符串匹配时,有普通群众思维和学霸青年思维
普通群众思维就是暴力破解,即将主串中所有与模式串长度一致的连续子串与模式串比较,这个过程中,主串索引会存在回退的过程,大大拉低效率。
学霸青年思维就是KMP匹配,在匹配时,主串索引一直是向前,不退后,只改变模式串的索引,这样匹配效率就大大提高了。
在KMP算法里,主要有两大问题需要理解: KMP原理 和 next数组计算 ,接下来会在对这两部分尽量进行解释一下。
KMP原理
首先我先放一篇我认为的比较好的博文资料,作为小白的我,也是看着博文一点一点慢慢学习的。http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html。
这篇博文我觉得对于初学者而言,足以理解KMP的原理了。其核心思想即为:,
在主串与模式串中各存在一个比较指针,指针所指的地方即为程序比较的地方,利用对模式串的信息的充分掌握,使其在与主串匹配的时候,灵活改变比较指针,使主串的比较指针一直向前,绝不退后。
用盗墓笔记中的一句话概括即为,"小三爷你大胆的往前走啊,往前走,莫回呀头"。
在这其中,最关键的就是在匹配的过程中,如何移动其比较指针的位置? 这就是大名鼎鼎的next数组。
Next数组
看了网上那么多的解释,我觉得这一个版本的解释最好懂,真是豁朗开朗http://www.cnblogs.com/tangzhengyue/p/4315393.html,由于自身水平有限,所以这里就不多说什么了,我怕越说越糊涂。关键就是计算模式串中每个字母
最长前后缀匹配。前后缀的解释在介绍KMP原理的那篇博文里已经写的非常清楚了。
下面就直接上代码吧,这样来的比较直接。
代码
def getNext(t):
j, i = -1, 0
next = [-1]*len(t)
while i < len(t)-1:
if -1 == j or t[i] == t[j]:
i, j = i + 1, j + 1
next[i] = j
else:
j = next[j]
return next def KMP(s,t):
next = getNext(t)
j, i = -1, -1
while j != len(t) and i < len(s):
if s[i] == t[j] or j == -1:
i, j = i + 1, j + 1
else:
j = next[j]
return (i-j,True) if j == len(t) else "None" print(KMP("ababxbabcdabdfdsss","abx"))
本来试着去解释一下程序,可是发现真的很难解释,next数组的求解程序中最关键的是如何初始化。KMP程序就相对比较好理解了。
好吧,最好的方法就是将代码放在IDE中单步调试,的每执行一部查看变量的情况,这样结合原理理解的最快。
[1]. 摘自百度百科KMP词条
Python ---- KMP(博文推荐+代码)的更多相关文章
- 博文推荐】Javascript中bind、call、apply函数用法
[博文推荐]Javascript中bind.call.apply函数用法 2015-03-02 09:22 菜鸟浮出水 51CTO博客 字号:T | T 最近一直在用 js 写游戏服务器,我也接触 j ...
- Python 学习书籍推荐
谁会成为AI 和大数据时代的第一开发语言? 这本已是一个不需要争论的问题.如果说三年前,Matlab.Scala.R.Java 和 Python还各有机会,局面尚且不清楚,那么三年之后,趋势已经非常明 ...
- Python入门方法推荐,哪些基础知识必学?
很多想入门的小伙伴还不知道Python应该怎么学,哪些知识必学,今天我们就来盘点一下. 01.入门方法推荐 总体来讲,找一本靠谱的书,由浅入深,边看边练. 网上的学习教程有很多,多到不知道如何选择.所 ...
- Python 开发工具推荐
对于开发工具,仁者见仁智者见智,关键是自己喜欢,用着顺手就好,不用刻意去追求别人用的是什么工具. 这里给大家主要推荐三款工具,分别是PyCharm.Sublime Text 3.VS Code,因为这 ...
- python中执行javascript代码
python中执行javascript代码: 1.安装相应的库,我使用的是PyV8 2.import PyV8 ctxt = PyV8.JSContext() ctxt.enter() ...
- python 人工智能资源推荐
原创 2017-06-05 玄魂工作室 玄魂工作室 我翻了翻我自己曾经看过的书,还是放弃了推荐.原因很简单,我对这个领域并不是很熟悉,我来推荐资源有点误人子弟.so,简单推点其他人建议给我的内容,希望 ...
- Python中文转拼音代码(支持全拼和首字母缩写)
本文的代码,从https://github.com/cleverdeng/pinyin.py升级得来,针对原文的代码,做了以下升级: 1 2 3 4 1.可以传入参数firstcode:如果为 ...
- 利用python实现电影推荐
"协同过滤"是推荐系统中的常用技术,按照分析维度的不同可实现"基于用户"和"基于产品"的推荐. 以下是利用python实现电影推荐的具体方法 ...
- c#代码 天气接口 一分钟搞懂你的博客为什么没人看 看完python这段爬虫代码,java流泪了c#沉默了 图片二进制转换与存入数据库相关 C#7.0--引用返回值和引用局部变量 JS直接调用C#后台方法(ajax调用) Linq To Json SqlServer 递归查询
天气预报的程序.程序并不难. 看到这个需求第一个想法就是只要找到合适天气预报接口一切都是小意思,说干就干,立马跟学生沟通价格. 不过谈报价的过程中,差点没让我一口老血喷键盘上,话说我们程序猿的人 ...
随机推荐
- Fedora下克隆Octopress博客
我在自己的github上搭建了一个Octopress博客(http://songlee24.github.io/),用于不定期的写一些学习笔记和心得体会.但是有时候由于换了电脑或者重装了linux系统 ...
- UVA 10555 - Dead Fraction(数论+无限循环小数)
UVA 10555 - Dead Fraction 题目链接 题意:给定一个循环小数,不确定循环节,求出该小数用分数表示,而且分母最小的情况 思路:推个小公式 一个小数0.aaaaabbb... 表示 ...
- Filters.h各种信号恢复滤波器头文件
这篇文章有部分原理:http://blog.csdn.net/u013467442/article/details/41125473 代码下载地址:http://read.pudn.com/downl ...
- Hibernate基于注解的双向one-to-many映射关系的实现
在项目中用到了一对多的实体类关系映射,之前接触的都是基于配置文件的映射实现.可是公司的大部分都是基于注解的.因此自己參考之前的代码捣鼓了基于注解的一对多的映射关系实现. 背景: 一的一端:QingAo ...
- splay专题复习——bzoj 3224 & 1862 & 1503 题解
[前言]快要省选二试了.上次去被虐出翔了~~这次即便是打酱油.也要打出风採!于是暂停新东西的学习.然后開始复习曾经的知识,为骗分做准备.PS:区间翻转的临时跳过,就算学了也来不及巩固了. [BZOJ3 ...
- jQuery 自定义动画效果
<!DOCTYPE html> <html> <head> <script src="/jquery/jquery-1.11.1.min.js&qu ...
- ios ionic 装平台 笔记
1.安装cnpm : npm install -g cnpm --registry=https://registry.npm.taobao.org 2.An error occurred when I ...
- Dictionary<string, string>是一个泛型使用说明
Dictionary<string, string>是一个泛型使用说明 Posted on 2010-08-05 15:03 moss_tan_jun 阅读(2273) 评论(0) 编辑 ...
- 洛谷 P3377 模板左偏树
题目:https://www.luogu.org/problemnew/show/P3377 左偏树的模板题: 加深了我对空 merge 的理解: 结构体的编号就是原序列的位置. 代码如下: #inc ...
- TypeScript `infer` 关键字
考察如下类型: type PromiseType<T> = (args: any[]) => Promise<T>; 那么对于符合上面类型的一个方法,如何得知其 Prom ...