第二章:KMP改良算法

第一章里面我们讲完了KMP算法的next数组实现法,回忆一下其实最重要的内容无非就是一、理解 i 指针无用回溯的意义,二、理解 j 指针的定位和模式串中每个元素重复度的关系,三、对next数组从观察到代码实现一条蛇式的理解掌握。 ps:文末有彩蛋哦。

自从BF暴力算法下岗之后呢,KMP算法就开始大行其道,当然也难怪,因为他大幅减少了算法的时间复杂度,而且还和朴素BF算法达到的效果一样,但是日子长了,这群众中难免有些不同的声音,有的人就说了,你KMP算法一直鼓吹自己不做无用功,那我今天就举个栗子给你,老子手里有一个主串S: "aaaabcde"   模式串T: "aaaaax" ,现在用KMP算法,先求出T串的next值, next[] = "012345",战斗开始

我们可以发现,第一次比较,当 i = j = 5 时,哥俩就不相等了,然后依照KMP的说法,next[5] = 4 ,所以 j 老老实实去了4位,但大家其实可以发现,前几位都一样的情况下,j 指针一个一个前推十分的憨,颇有被KMP干掉的BF暴力算法的风范,故 ②③④⑤完全是多余步骤,别怀疑,第五步也是多余的。

那么发现了问题,KMP算法感受到了前所未有的惊慌,即将被遗忘在历史舞台的风险使他奔溃,他是决计不想蹈BF的覆辙,但这时,他生命中的贵人出现辽,这就是 nextval[ ] 数组。

nextval 说了,刚才这个例子里的问题,完全在于你现在聘用的next数组不给力,如果你在刚才例子的第二步就返回模式串的第一位,就可以进一步避免无用功,那么我们来看一看 nextval[ ] 数组和 next [ ] 数组的差别在哪里,我们先看看怎么 由next 推出 nextval

像它这样碌碌无为的串,看看nextval怎么得出, 定义 nextval[1] = 0 。第二个元素 b  仔细看, 因为next[2] = 1 ,我们就去找第一个元素, a 显然不等于b,这时,nextval[2] = next[2] = 1。第三个元素 a ,next等于几? 等于 1 ,第一个元素和第三个是相等的 ,则 nextval[3] = nextval[1] = 0。后面的如法炮制,不多说了,附上完整nextval,自己观察算了之后对比一哈,笔者感觉算了这个比较容易理解代码。

蛮简单对不对

OK,展示一哈  get_nextval  代码给大家,同时 next 数组 正式下岗

至于KMP算法只要把原来的 next 改成 nextval 就好,不再赘述,KMP改良算法也就这样辣

对嘛,其实也不难,8要放弃

彩蛋呢在这里:

附上next数组和nextval数组的观察得数方法———瞪眼法

 next数组瞪眼法

第一位的next值为0,第二位的next值为1,这是确定的,无论前两位相不相等,后面求解每一位的next值时,根据前一位进行比较。首先将前一位与其next值对应的内容进行比较,如果相等,则该位的next值就是前一位的next值加上1;如果不等,向前继续寻找next值对应的内容来与前一位进行比较,直到找到某个位上内容的next值对应的内容与前一位相等为止,则这个位对应的值加上1即为需求的next值;如果找到第一位都没有找到与前一位相等的内容,那么需求的位上的next值即为1。

我们来操练一个:

第一位是 : 0

第二位是 : 1

第三位开始,先看第二位的 next 是 1 ,那么第一位是 a ,我们第三位的前一位即 b 和 这个next 值指向的 a 显然不等,而且这个 a 已经是第一位了,那么我们在这个位置 1

第四位开始,先看第三位的next 是 1,而第三位和第一位相等,这时第四位的 next 值就是第三位的 next 值+1,即第四位置 2

第五位开始,先看第四位的next 是 2,找第二位,发现不等,看第二位的next,发现是1,第二位和第一位比较,还是不等,置1,ok

。。。。

剩下的自己操练一哈

给答案辽

 nextval数组瞪眼法

上面详细讲了 next 数组的观察法,有了 next ,要观察nextval简直不要太简单,在第二章已经有了明确方法,这里不再赘述,而且直接读代码相信机滞的你也没问题

KMP 完

(原创)白话KMP算法(续)的更多相关文章

  1. (原创)白话KMP算法详解

    引子:BF暴力算法 KMP算法知名度相当高,燃鹅其理解难度以及代码实现对于初学数据结构和算法的同学并不友好,经过两天的总结,详细总结KMP算法如下: 初学串的模式匹配时,我们都会接触到,或者说应该能想 ...

  2. 【原创】KMP算法代码(C)

    //s是模式字符串,t是匹配字符串(可以看我上一篇文章中的叙述) int KMP(const char * s , const char * t) { int slen = strlen(s) , t ...

  3. (原创)详解KMP算法

    KMP算法应该是每一本<数据结构>书都会讲的,算是知名度最高的算法之一了,但很可惜,我大二那年压根就没看懂过~~~ 之后也在很多地方也都经常看到讲解KMP算法的文章,看久了好像也知道是怎么 ...

  4. 【原创】通俗易懂的讲解KMP算法(字符串匹配算法)及代码实现

    一.本文简介 本文的目的是简单明了的讲解KMP算法的思想及实现过程. 网上的文章的确有些杂乱,有的过浅,有的太深,希望本文对初学者是非常友好的. 其实KMP算法有一些改良版,这些是在理解KMP核心思想 ...

  5. KMP算法详解-彻底清楚了(转载+部分原创)

    引言 KMP算法指的是字符串模式匹配算法,问题是:在主串T中找到第一次出现完整子串P时的起始位置.该算法是三位大牛:D.E.Knuth.J.H.Morris和V.R.Pratt同时发现的,以其名字首字 ...

  6. (原创)数据结构之利用KMP算法解决串的模式匹配问题

      给定一个主串S(长度<=10^6)和一个模式T(长度<=10^5),要求在主串S中找出与模式T相匹配的子串,返回相匹配的子串中的第一个字符在主串S中出现的位置. 输入格式: 输入有两行 ...

  7. 算法:KMP算法

    算法:KMP排序 算法分析 KMP算法是一种快速的模式匹配算法.KMP是三位大师:D.E.Knuth.J.H.Morris和V.R.Pratt同时发现的,所以取首字母组成KMP. 少部分图片来自孤~影 ...

  8. KMP算法学习

    kmp算法完成的任务是:给定两个字符串O和f,长度分别为n和m,判断f是否在O中出现,如果出现则返回出现的位置.常规方法是遍历a的每一个位置,然后从该位置开始和b进行匹配,但是这种方法的复杂度是O(n ...

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

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

随机推荐

  1. 如何确定VS编译器版本

    _MSC_VER是MSVC编译器的内置宏,定义了编译器的版本,_MSC_VER 值对应版本关系 MSVC++ 11.0 _MSC_VER = 1700 (Visual Studio 2012)  MS ...

  2. wordpress建设的企业网站

    wordpress企业站 http://ahlajd.demo.phpfangzhan.com 后台焦点图实现:

  3. sql server 中数据库数据导入到另一个库中

    这篇说了sql语句对于备份的数据库进行还原 ,如果数据量大了还是什么问题,发现我的数据丢失了一些,头疼 sql server 备份还原 下面使用的的数据导入来解决这个问题,因为数据量比较大,导出来的脚 ...

  4. MQTT初始篇笔记整理

    MQTT简介 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输),基于TCP/IP 协议栈而构建,虽然叫消息队列遥测传输,但是她与消息队列毫无关系,她 ...

  5. vue2.0移除或更改的一些东西

    一.vue2.0移除了$index和$key 虽然说现在很多文章说他们的代码是vue2.0版本的,但是有一些仔细一看,发现并不全是2.0版本,有些语法还是1.0的版本,比如这个$index,$key, ...

  6. ccenteros 部署 redis

    step one :  yum install redis    -- 安装redis数据库 step two:安装完成之后开启redis 服务 service redis start   syste ...

  7. C++新闻检索类

    研究长字符串快速全文检索技术,实现某电力公司新闻中心新闻稿件全文检索统计系统. 1. 设计实现适合新闻稿件的基础类库 2. 新闻稿件全文检索功能实现 3. 新闻稿件按照关键字统计查询   代码如下 P ...

  8. C++求值顺序

    <C++Primer5th>中文版第124页 C++语言没有明确规定大多数二元运算符的求值顺序, 给编译器优化留下了余地. 这种策略实际上是在代码生成效率和程序潜在缺陷之间进行了权衡,这个 ...

  9. BZOJ2659: [Beijing wc2012]算不出的算式(数学)

    Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1575  Solved: 939[Submit][Status][Discuss] Descriptio ...

  10. Linux centos7 安装python3 及 GCC

    1.用wget下载python源码 PYTHON下载 找适合自己的版本,我下载的是3.7.2 2.用tar命令解压下载的文件 tar -zxvf Python-3.7.2.tgz 3.进入目录解压后的 ...