直接把作业帖上来是不是有点不太公道呀。。。

无所谓啦反正各位看着开心就行

KMP算法

对于模式串$P$,建立其前缀函数$ N$ ,其中$N [q] $ 表示在$P$中,以$q$位置为结束的可以匹配到前缀的最长后缀的长度(也可以理解为那个前缀的结束位置),在匹配中,若$P[i]$与$S[j]$失配,则令$i=N [i-1] +1$ ,否则$i=i+1,j=j+1$

现考虑如何构造$N$ ,设当前以计算出$N[1..i-1]$ ,则令$k=N[i-1]$ ,若 $P[k+1]=P[i]$,则令$N[i]=k+1$ ,否则令$k=N[k]$ 。重复上述过程,直至找到$N[i]$

可证该算法能在$\Theta(|P|) $ 的时间内构造出前缀函数$N$ ,在$\Theta (|S|)$ 的时间内完成匹配,总的时间复杂度为$\Theta(|S|+|P|)$

KMP算法的正确性证明

先证明匹配过程的正确性:

在过程中,若$P[1..q]$ 与$S[s+1...s+q]$ 匹配,而$P[q+1]$与$S[s+q+1]$ 失配,那么由$N$的定义可立即得出$P[1..N[q]]$ 与 $S[s+q-N[q]+1...s+q]$ 匹配,而$S[1...t]$与$S[s+q-t+1...s+q]$ 失配$(N[q]<t<q)$ ,即只需检验$P[N[q]+1]$ 与$S[s+q+1]$ 的匹配情况即可,匹配过程的正确性即可得证。

接下来证明前缀函数$N$计算的正确性:

令$N^*[q]= \{N[q],N^{(2)}[q],…,N^{(t)}[q]\}$ 其中$N^{(t)}[q]=N^{(t-1)}[q],N^{(0)}[q]=N[q]$ ,那么$N^*[q]$ 为以q位置为结束的可以匹配到前缀的后缀的所有长度(即匹配到所有前缀的位置),同时有$N[q]-1\in N^*[q-1]$ ,因此只需从大到小枚举$N^*[q-1]$ 中的元素并通过判断即可得出$N[q]$ 。
KMP算法的时间复杂度证明

在匹配时:$i,j$增长了$|S|$ ,而在$i=N[i-1]+1$ 中,$i$ 至少减少1,即该语句至多执行了$|S|$次,因此时间复杂度为$\Theta(|S|)$。

构造前缀函数$N$ 时: 我们考虑k的变化,我们可以得到,在每次$k=N[k]$ 中,$k$ 至少减少1,又因为$k$随$i$增加了$|P|$次,即该语句至多执行$|P|$ 次,因此时间复杂度为$\Theta(|P|)$ 。

因此总的时间复杂度为$\Theta(|S|+|P|)$ 。
KMP算法的优化

我们希望通过优化,为了减少失配的概率,因此提出如下改进:

在构造$N'$数组时,当$P[k+1]=P[i]$ 时,若$P[i+1]=P[k+2]$ 则$N'[i]=k+1$ 否则$N'[i]=N'[k+1]$ 。
该优化的正确性证明

在匹配时,我们发现,若$P[q+1]$ 与$S[s+q+1]$失配,同时$P[q+1]=P[N^{(t)}[q]+1]$ ,则$P[N^{(t)}[q]+1]$一定与$S[s+q+1]$ 失配,因此若$P[N[q]+1]=P[q+1]$ ,则该比较一定失配,无需考虑。

在该优化中,由该函数的递归求法可得,$N'[q]=max\{N^*[q]且P[q+1]\neq P[N^{(t)}[q]+1]\}$ ,因此$N'[q]$ 依旧能枚举完所有可能匹配的前缀,同时减少失配概率。
该优化对算法空间与时间复杂度的影响

由于该优化只是改变了N数组的构造方法,因此对空间复杂度无影响。

时间复杂度的证明同KMP的证明,可得对最坏情况下的时间复杂度无影响

由于该算法避免了出现$P[N[q]+1]=P[q+1]$的情况,因此对于有较多重复子串的模式串有较好的优化效果(如aaaab,abcabcabcd)

转载于:https://www.cnblogs.com/New-Godess/p/5931907.html

KMP算法的正确性证明及一个小优化相关推荐

  1. 3.Sunday算法的一个小优化

    优化算法思路: 1.Sunday算法关键思想 通过解析传统Sunday算法我发现它实现跳转的关键思想在于第二步,我们深入解析下第二步的原理: we should working hard work h ...

  2. Python基于用户协同过滤算法电影推荐的一个小改进

    之前曾经推送过这个问题的一个实现,详见:Python基于用户协同过滤算法的电影推荐代码demo 在当时的代码中没有考虑一种情况,如果选出来的最相似用户和待测用户完全一样,就没法推荐电影了.所以,在实际 ...

  3. [转]数据结构KMP算法配图详解(超详细)

    KMP算法配图详解 前言 KMP算法是我们数据结构串中最难也是最重要的算法.难是因为KMP算法的代码很优美简洁干练,但里面包含着非常深的思维.真正理解代码的人可以说对KMP算法的了解已经相当深入了.而 ...

  4. 数据结构KMP算法配图详解(超详细)

    KMP算法配图详解 前言 KMP算法是我们数据结构串中最难也是最重要的算法.难是因为KMP算法的代码很优美简洁干练,但里面包含着非常深的思维.真正理解代码的人可以说对KMP算法的了解已经相当深入了.而 ...

  5. 2020年最全最简单KMP算法讲解

    目录 1.KMP算法的来源 2.最大公共前后缀 3.KMP算法原理 4.next数组 5.next数组值的确定 6.KMP算法的缺陷 7.KMP算法的改进 1.KMP算法的来源 其实博主刚看KMP算法 ...

  6. KMP算法——从入门到懵逼到了解

    本博文參考http://blog.csdn.net/v_july_v/article/details/7041827 关于其它字符串匹配算法见http://blog.csdn.net/WINCOL/a ...

  7. 【数据结构】详解KMP算法

    字符串匹配算法:简单来说就是给你一个主串和一个子串,让你查找子串在主串中的位置,找到返回下标. 常见的两种算法:BF算法.KMP算法 这两种算法是怎样的思路呢,我们接着往下看: 目录 BF算法(暴力算 ...

  8. 【KMP算法详解——适合初学KMP算法的朋友】

    相信很多人(包括自己)初识KMP算法的时候始终是丈二和尚摸不着头脑,要么完全不知所云,要么看不懂书上的解释,要么自己觉得好像心里了解KMP算法的意思,却说不出个究竟,所谓知其然不知其所以然是也. 经过 ...

  9. 【转】KMP算法详解

     原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任. http://billhoo.blog.51cto.com/2337751/411486 ...

  10. 字符串的KMP算法--Python实现

    KMP算法Python实现 今天研究KMP算法,看来很多版本,有不同的语言写的,但是感觉越看越乱,最后自己试着写一份进行总结 首先,KMP算法使字符串匹配中的优化算法,使原来的O(m*n)降到了O(m ...

最新文章

  1. 突破磁盘低级检测实现文件隐藏
  2. vue 打包html静态页面,Vue.js打包部署到服务器路径资源和页面404
  3. bzoj1297 [SCOI2009]迷路(矩阵优化)
  4. XtraBackup做mysql主从同步
  5. 多彩投网站动态爬取[python+selenium]
  6. VTK:几何对象之ConeDemo
  7. SpringBoot2.x 整合 Ueditor
  8. 再谈RetinaNet
  9. 图解 Python 函数
  10. 问题分析与解决——ADSL错误代码(转)
  11. 常用汉字字体字号的介绍及选用原则
  12. AI数学基础之:P、NP、NPC问题
  13. 研究称在家中工作可提高员工工作效率
  14. 从《大国崛起》(英国)看中国软件的发展
  15. 全球及中国隐形眼镜护理液行业消费规模及投资竞争力分析报告2021-2027年
  16. sql 获取当前年份的12个月
  17. 检测PE文件的有效性
  18. 对LBP与HOG的理解
  19. add-migration 多个DbContext
  20. Vue学习 — 详解Vue生命周期

热门文章

  1. NVIDIA显卡超过一定路数,性能急剧下跌
  2. C的byte数组在python中的处理
  3. linux 查看pgsql端口,如何通过Linux脚本检查是否已安装PostgreSQL?
  4. python集合特点和注意事项_Python:list 和 array的对比以及转换时的注意事项
  5. 双目摄像头的帧同步输入fsync信号_读源码长知识 | Android卡顿真的是因为”掉帧“?...
  6. deeplinux 热点_在深度deepin linux系统中同时开启wifi与热点的办法
  7. python类方法和实例方法的区别_python中的类方法,实例方法和静态方法的区别
  8. mysql redo log 几个组_必须了解的mysql三大日志,你知道几个?
  9. 第6章:可维护性软件构建方法 6.1可维护性的度量和构造原则
  10. opencv:基于颜色空间的肤色检测方法