引言

KMP算法应该是看了一次又一次,比赛的时候字符串不是我负责,所以学到的东西又还给网上的博客了……

退役后再翻开看,看到模板,心想这不是\(O(n^2)\)的复杂度吗?

有两个循环也不能看做是\(O(n^2)​\)的,这要用到摊还分析.

模板

这里用到的模板是算竞上的

  • calc_next()
    Next[1] = 0;
for (int i = 2, j = 0; i <= n; ++i) {
while (j > 0 && a[i] != a[j + 1]) j = Next[j];
if (a[i] == a[j + 1]) ++j;
Next[i] = j;
}
  • kmp()
   for (int i = 1, j = 0; i <= m; ++i) {
while (j > 0 && (j == n || b[i] != a[j + 1]))j = Next[j];
if (b[i] == a[j + 1])++j;
f[i] = j;
}

可以发现上下两个函数挺像的,Next[i]含义就是模式串以\(i\)结尾的子串([1..i]的后缀)与模式串的前缀能匹配的最长长度

证明

观察发现有两个操作:

  • 匹配成功:j++,这个代价是1
  • 匹配失败: j=Next[j]还要经过while循环,这个代价未知

根据记账法,假设每个平摊代价是2,对于每个匹配成功的操作,其中1元用来j++,另1元就存起来,给后面匹配失败时用:

而当失配的时候,就会用到银行存款,最坏的情况当然就是用光了所有存款,但可以发现每个匹配的操作分配两个时间代价是完全足够的

换句话说,你使用存款肯定得要求银行有存款,而每次j++操作都会存1元,在当前j前面必然每个位置都是有大于等于1的存款

所以复杂度就是j++次数的两倍,也就是匹配串的长度 \(2n\)

根据平摊分析要求\(\check c_i \ge c_i\),平摊代价设置为\(2\)是完全满足的

综上所述:KMP算法两个函数的总体运算次数为\(2n+2m\),复杂度是\(O(n+m)\)

总结

也不知道这样分析对不对,如果只是感性理解的话足够了.

也有势能法的做法,但是这样的话就要定义势能函数,我觉得记账法还是好理解一点.

KMP算法复杂度证明的更多相关文章

  1. KMP算法的正确性证明及一个小优化

    直接把作业帖上来是不是有点不太公道呀... 无所谓啦反正各位看着开心就行 KMP算法 对于模式串$P$,建立其前缀函数$ N$ ,其中$N [q] $ 表示在$P$中,以$q$位置为结束的可以匹配到前 ...

  2. 算法导论17:摊还分析学习笔记(KMP复杂度证明)

    在摊还分析中,通过求数据结构的一系列的操作的平均时间,来评价操作的代价.这样,即使这些操作中的某个单一操作的代价很高,也可以证明平均代价很低.摊还分析不涉及概率,它可以保证最坏情况下每个操作的平均性能 ...

  3. 浅析KMP算法

    浅析KMP算法 KMP算法是一种线性字符串的匹配算法,将主串S与模式串T匹配. 首先朴素算法大家都会,就是直接从S的每一个位置开始,枚举比较,时间效率为O(nm),现在要想到一种化简的方式,使得时间复 ...

  4. 字符串匹配算法——KMP算法学习

    KMP算法是用来解决字符串的匹配问题的,即在字符串S中寻找字符串P.形式定义:假设存在长度为n的字符数组S[0...n-1],长度为m的字符数组P[0...m-1],是否存在i,使得SiSi+1... ...

  5. 关于KMP算法理解(快速字符串匹配)

    参考:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html 2016-08- ...

  6. 【BZOJ3670】动物园(KMP算法)

    [BZOJ3670]动物园(KMP算法) 题面 BZOJ 题解 神TM阅读理解题 看完题目之后 想暴力: 搞个倍增数组来跳\(next\) 每次暴跳\(next\) 复杂度\(O(Tnlogn)\) ...

  7. 算法进阶面试题01——KMP算法详解、输出含两次原子串的最短串、判断T1是否包含T2子树、Manacher算法详解、使字符串成为最短回文串

    1.KMP算法详解与应用 子序列:可以连续可以不连续. 子数组/串:要连续 暴力方法:逐个位置比对. KMP:让前面的,指导后面. 概念建设: d的最长前缀与最长后缀的匹配长度为3.(前缀不能到最后一 ...

  8. 【BZOJ3670】【NOI2014】动物园(KMP算法)

    [BZOJ3670]动物园(KMP算法) 题面 BZOJ 题解 神TM阅读理解题 看完题目之后 想暴力: 搞个倍增数组来跳\(next\) 每次暴跳\(next\) 复杂度\(O(Tnlogn)\) ...

  9. 简单有效的kmp算法

    以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...

随机推荐

  1. Spring 事件(2)- 自定义事件

    Spring 系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of ...

  2. 51nod 1430:奇偶游戏 博弈

    1430 奇偶游戏 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题  收藏  关注 有n个城市,第i个城市有ai个人.Daene ...

  3. 15 —— npm —— package.json 与 package-lock.json 的作用

    一,package.json  是 npm init 时创建的一个文件,会记录当前整个项目中的一些基础信息. 二,package-lock.json 是 node_modules 文件夹或者 pack ...

  4. java向python ,text文件动态传参或传值问题完美解决

    由于业务需要对python文件进行参数传递,通过下面两个java方法完美解决此问题,我的思路是:首先我要先把上次写的参数删除,第二我要新的参数写到python文件中. 第一个方法解决了删除上次传递的参 ...

  5. idea导入新项目后右键main方法没有Run xxx.main()

    刚安装的idea2019.1,基本上没有什么配置.导入从github clone下来的工程.鼠标右键main方法时没有发现 run 选项,如下图所示: 这里是配置有问题造成的,对比下正常的工程,可以发 ...

  6. 二十五、CI框架URL辅助函数之base_url函数

    一.在UI根目录新建一个pic目录,里面放一个图片,如下 二.在我们打View里面写入一下代码,base_ur函数返回的是网站根目录,代码见附图: 三.两种写法,显示效果如下: 四.我们查看浏览器的源 ...

  7. 十四、CI框架之数据库以参数形式插入操作

    一.代码如下: 二.使用浏览器打开 三.我们查看数据库,被成功插入数据 不忘初心,如果您认为这篇文章有价值,认同作者的付出,可以微信二维码打赏任意金额给作者(微信号:382477247)哦,谢谢.

  8. 《新标准C++程序设计》2.4-2.6(C++学习笔记4)

     1.对象的内存匹配 一般来说,在C++中,一个对象占用的内存空间大小等于其成员变量所占用的内存空间的大小之和.(对象只包含成员变量,不包含成员函数) 每个对象都有各自的存储空间.一个对象的某个成员变 ...

  9. oracle11g忘记管理员密码

    oracle的sys和system密码是我们经常忘记的,忘记之后我们可以通过sqlplus来修改重置. 首先打开sqlplus:在运行处可直接输入打开 进入窗口后,首先输入 sqlplus/as sy ...

  10. 吴裕雄--天生自然 JAVASCRIPT开发学习: Break 和 Continue 语句

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...