理解我接下来所说的东西,需要大家懂得简单的动态规划。

KMP大家都不陌生了,但是其中计算next数组总是搞不明白,我想有很多人和我一样。所以这里用动态规划的思路去描述一下这个问题。

模式串P=c[1]c[2]......c[n]

先设几个符号:

suffix(S): S的所有后缀的集合

prefix(S): S的所有前缀的集合

例如:suffix("abcd") = {"","d", "cd", "bcd"}

prefix("abcd") = {"","a", "ab", "abc"}

看到,在这两个集合都除去了"abcd"本身。

真对P定义next的意义:next[i]代表的意义是suffix(c[1]c[2]......c[i])与prefix(c[1]c[2]......c[i])两个集合中最长相同串的长度(不包括串c[1]c[2]......c[i])。那么如何计算next呢?其实这个计算过程类似动态规划的转移过程,从初始状态,不断的根据转移方程计算,直至计算出所有的可达状态。

那么状态怎么定义?初始条件是什么?

设两个游标p1,p2, p1,p2构成的位置对为状态<p1,p2>,例如p1在i位置,p2在j位置,i<j,那么状态<i, j>就代表c[1]c[2]......c[i]=c[j-i+1]c[j-i+2]......c[j],即串的前i个字符与后i个字符相同。之后我们根据<i,j>推出<i',j+1>。我们依次计算<i1, 1>,<i2,2>,......,<in,n>。设LMAX(<i, j>)=i,通过上面对next的定义,我们可知next[j]=MAX{LMAX(<i,j>)|0<=i<j}。

初始化的条件为 next[1] = LMAX(<0, 1>) = 0。假设我们当前所在的状态为<i, j>,那么如何推出<i',j+1>呢?这必须得看c[i+1]与c[j+1]的关系,如果c[i+1]=c[j+1],那么我们到达<i+1,j+1>的状态;如果c[i+1]!=c[j+1],那么我们得根据所有可能的<i', j>状态,判断c[i'+1]=c[j+1]是否成立,如果成立就到达<i'+1,j+1>状态。那么,我们如何找到这些合法的<i',j>状态呢?很庆幸,因为next数组中天然的保存了我们需要的信息。当我们到达<i,j>这个状态并且发现c[i+1]!=c[j+1],那么下一个尝试的状态将是<next[i], j>,看看c[next[i]+1]=c[j+1]是否成立。而且我们发现,只要按照i,next[i],next[next[i]]......这样下去找到第一个能够符合转移条件的状态就OK了,如果没有一个能够使之转移的状态,就说明没有一个前缀和当前的某个后缀是相等的,那么直接跳转到<0, j+1>这个状态。

举个例子吧: S=abcababc为了方便理解,在S前加一个通配符$$abcababc          <0, 1>             next[1]=0
||$abcababc          <0, 2>             next[2]=0
| | $abcababc          <0, 3>             next[3]=0
|  |$abcababc          <1, 4>             next[4]=1|  | $abcababc          <2, 5>             next[5]=2|  |下一步s[3]!=s[6],这将尝试状态<next[3],j>=<0,j>,使之转移到下面的状态$abcababc          <1, 6>             next[6]=1|    | $abcababc          <2, 7>             next[7]=2|    |$abcababc          <3, 8>             next[8]=3|    |

到此,有的同学又有疑问了,人家KMP定义的next[i]的意义和你的也不一样呀。对,确实不一样。

KMP中对next[i]的定义为:设文本串为T,模式串为P,p[i]!=T[j]时,应该用p[?]与T[j]进行比较。

对应于上例,得到的next数组值应为

KMP的next: -1 1 1 1 2 3 2 3
我们的next:  0 0 0 1 2 1 2 3

怎么通过我们的next获取到正确的next呢?非常简单,从后往前循环做next[i] = next[i-1]+1,之后next[1]=-1就哦了。

KMP算法的动态规划解说相关推荐

  1. 【Java数据结构与算法】第十八章 动态规划和KMP算法

    第十八章 动态规划和KMP算法 文章目录 第十八章 动态规划和KMP算法 一.动态规划 1.介绍 1.爬楼问题 2.扔鸡蛋问题 3.背包问题 二.KMP算法 1.引入 2.介绍 2.代码实现 一.动态 ...

  2. 1道动态规划(搬箱子)、KMP算法、图(Prim算法)、1道哈夫曼树

    1.最长递增子序列 华华要给厂里进一批新箱子共n个(n<=500),编号为1到n,用一个正整数ai(1<=ai<=10000)(1<=i<=n)来表示编号为i的箱子的高度 ...

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

    2019独角兽企业重金招聘Python工程师标准>>> KMP算法完整教程 全称:                               Knuth_Morris_Pratt ...

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

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

  5. KMP算法之 好理解的模板

    主要作用:能够在线性复杂度内求出一个串在另一个串的所有匹配位置. 说明:设模板串是 pattern, 令 next[i] = max{k|[pattern[0..k−1] = pattern[i−k+ ...

  6. KMP算法的Next数组详解(转)

    转载请注明来源,并包含相关链接. 网上有很多讲解KMP算法的博客,我就不浪费时间再写一份了.直接推荐一个当初我入门时看的博客吧: http://www.cnblogs.com/yjiyjige/p/3 ...

  7. 详解KMP算法原理,以及完整java与C++实现

    点击此处学习更多算法与通信知识 作者 | labuladong 来源 | labuladong KMP 算法(Knuth-Morris-Pratt 算法)是一个著名的字符串匹配算法,效率很高,但是确实 ...

  8. 字符串匹配(KMP 算法 含代码)

    主要是针对字符串的匹配算法进行解说 有关字符串的基本知识 传统的串匹配法 模式匹配的一种改进算法KMP算法 网上一比較易懂的解说 小样例 1计算next 2计算nextval 代码 有关字符串的基本知 ...

  9. KMP算法的java实现

    package com.trs.utils;public class KMPStr {/** 在KMP算法中,最难求的就是next函数,如何理解next函数是一个难题,特别是k=next[k],这里* ...

最新文章

  1. 除了数据属性,Vue 实例还提供了一些有用的实例属性与方法。它们都有前缀 $,以便与用户定义的属性区分开来。
  2. ant文件放在ps的哪里_ant design vue按需导入icons
  3. ubuntu 20.04 安装circos
  4. C++并发编程实战(豆瓣评分5.4)
  5. 利用指针编程实现:删除一个字符串中的所有空格 c语言,C语言必考100题解析汇报...
  6. leetcode - 516. 最长回文子序列
  7. System.BadImageFormatException: 试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)...
  8. mybatis一个怪异的问题: Invalid bound statement (not found)
  9. 处理器好点是否上网就快些?
  10. 程序员为什么要懂物联网?
  11. node.js 框架基本功能
  12. 草根站长的创业路:说说这两年的创业经历
  13. wincc安装信息服务器,WinCC 7.4软件不会安装?怎么授权?一文教会你
  14. opensips服务端搭建
  15. 阻止原生输入中文拼音途中会触发input方法的问题
  16. uniapp html5+ plus蓝牙连接电子秤
  17. ettercap进行简单的arp欺骗和中间人攻击
  18. 条码打印软件引用其他对象内容的方法
  19. 飞天 AI 平台重磅发布!阿里拥抱 AI 这五年
  20. 【安安教具】-【数学】-【数轴】模拟器 教你如何用python制作数轴模拟器 python 小项目创作

热门文章

  1. webpack+react多页面开发架构
  2. apache 与 php-fpm 几种处理方式
  3. Java基础巩固——反射
  4. Broadcom BCM4322(如:HP 6530b)wifi不能用解决办法
  5. 关于Postfix邮件网关无法重启问题
  6. HTML5的Video标签的属性,方法和事件汇总
  7. 对抽象工厂+反射+配置文件的实例理解
  8. Asp.net页面间传值方式汇总
  9. RTOS之uCOS-II源码下载及源码目录结构、常见的RTOS!
  10. 剑指offer三:从尾到头打印链表