zoukankan      html  css  js  c++  java
  • (原创)白话KMP算法(续)

    第二章: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 完

  • 相关阅读:
    同样功能的SQL语句,写成参数和写成常量怎么效率会有那么大的差别
    遭遇钓鱼网站
    SQL Server 2005与Oracle同步注意NUMBER类型转换
    Oracle数据类型(转)
    如何使用枚举的组合值
    社保,交得越多亏得越多(转)
    使用OPENXML函数将XML文档转换为行结果集
    发布一个性能测试工具的破解补丁
    如何将SQLServer2005中的数据同步到Oracle中
    Repository模式
  • 原文地址:https://www.cnblogs.com/yx1999/p/10350004.html
Copyright © 2011-2022 走看看