笔记:KMP的复习
Record
一个重要的字符串算法,这是第三次复习。
通过总结我认为之所以某个算法总是忘记,是因为大脑始终没有认可这种算法的逻辑(也就是脑回路)。
本篇主要讲解从KMP的应用场景,再到算法知识,以及例题。
Main
现有两个字符串 \(A, B\),求出 \(A\) 在 \(B\) 中出现的次数。
范围:字符串长度均 \(\leq 1e6 + 10\)。
其实简单来说,KMP就是优化了双重循环,解决字符串的匹配问题。
所以个人总结一下,遇到字符串的题目,如果dp用不了就考虑哈希和KMP
数学上从特殊到一般,那么这里我们从暴力到优化。
以 \(A = abab , B = abababaaabb\) 为例,一般做法是双重循环,时间复杂度 \(O(n ^ 2)\)。
我们来看这个具体是怎么实现的。
每次枚举一个初始点,然后一位一位的判断是否相同。如果相同,就继续判断直到;如果不同,就退出并且选择下一个点作为初始点。
首先,如果说判断到第 \(k\) 位发现不对,不是彻底无法挽救的。如果说这个子串从 \(1 .. k - 1\) 的前缀和后缀都没有相同的,比如说这种 \(abcfd\),那么判断过的位也不用再判断了,因为往后移一位就都错开了,所以就一直往后推,判断起点是否相同,相同就开始一位一位继续判断。如果说是这种 \(abcabc\) 那就好办了,因为我们可以进行如下的操作。
abcabcbdde
abcabcd
这个时候再第七位发现有问题了,是不是全部跳过呢?当然不是。
abc|abcbdde
|abcabcd
再从相同的前缀开始就可以了。只不过显然这个情况下还是匹配不了。
for(int i = 1, j = 0; i <= m; i ++ )
{
while(j && b[i] != a[j + 1]) j = ne[j];
if(b[i] == a[j + 1]) j ++ ;
if(j == n)
{
cout << i - n << ' ';
j = ne[j];
}
}
通过这样的思路,只需要每次遍历一遍母串,时间复杂度 \(O(n)\)。
在匹配之前,得要算一下子串中每一位对应的最长的前缀和后缀,记录下前缀的最后一位。
for(int i = 2, j = 0; i <= n; i ++ )
{
while(j && a[i] != a[j + 1]) j = ne[j];
if(a[i] == a[j + 1]) j ++ ;
ne[i] = j;
}
例题
利用ne数组的性质,马上就可以得到一个字符串最长的相同前缀和后缀。观察发现,存在循环节的字符串观察可知:
- 当第 \(i\) 位存在 \(i \mod{(i - ne_i)} = 0\),那么他的循环节一定是 \(i - ne_i + 1 ... i\),个数是 \(i / (i - ne_i)\)。
这个自己打打草稿就出来了,不多说了。
笔记:KMP的复习的更多相关文章
- mybatis学习笔记之基础复习(3)
mybatis学习笔记之基础复习(3) mybatis是什么? mybatis是一个持久层框架,mybatis是一个不完全的ORM框架.sql语句需要程序员自己编写, 但是mybatis也是有映射(输 ...
- KMP算法复习笔记
KMP 算法 KMP 算法是一种改进的字符串匹配算法,KMP 算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的.具体实现就是实现一个next()函数,函数本身包含了 ...
- KMP算法复习【+继续学习】
离NOIP还剩12天,本蒟蒻开始准备复习了. 先来个KMP[似乎我并没有写过KMP的blog] KMP KMP算法是解决字符串匹配问题的一个算法,主要是单对单的字符串匹配加速,时间复杂度O(m + n ...
- 【JS复习笔记】07 复习感想
好吧,其实<JavaScript语言精粹>后面还简单介绍了代码风格,优美特性,以及包含的毒瘤.糟粕. 但我很快就看完了,发现其实都在前面讲过了,所以就不写了. 至今为止已经算是把JavaS ...
- 学习笔记-KMP算法
按照学习计划和TimeMachine学长的推荐,学习了一下KMP算法. 昨晚晚自习下课前粗略的看了看,发现根本理解不了高端的next数组啊有木有,不过好在在今天系统的学习了之后感觉是有很大提升的了,起 ...
- 原型及原型链,以及prototype和__proto__属性(笔记便于以后复习)
首先,js的数据结构有 原始类型(5种):Boolean.Number.String.Null.Underfined, 然后是引用类型:Array.Date.Error.RegExp.Function ...
- <数据结构与算法分析>读书笔记--数学知识复习
数学知识复习是<数据结构与算法分析>的第一章引论的第二小节,之所以放在后面,是因为我对数学确实有些恐惧感.不过再怎么恐惧也是要面对的. 一.指数 基本公式: 二.对数 在计算机科学中除非有 ...
- 算法笔记--KMP算法 && EXKMP算法
1.KMP算法 这个博客写的不错:http://www.cnblogs.com/SYCstudio/p/7194315.html 模板: next数组的求解,那个循环本质就是如果相同前后缀不能加上该位 ...
- 算法导论17:摊还分析学习笔记(KMP复杂度证明)
在摊还分析中,通过求数据结构的一系列的操作的平均时间,来评价操作的代价.这样,即使这些操作中的某个单一操作的代价很高,也可以证明平均代价很低.摊还分析不涉及概率,它可以保证最坏情况下每个操作的平均性能 ...
- python笔记18(复习)
今日内容 复习 内容详细 1.Python入门 1.1 环境的搭建 mac系统上搭建python环境. 环境变量的作用:方便在命令行(终端)执行可执行程序,将可执行程序所在的目录添加到环境变量,那么以 ...
随机推荐
- Java常见的线程池的创建及使用
文章目录 线程池是什么? 线程池的主要参数 线程池的拒绝策略 创建线程池的方式 关闭线程池 大家好,我是Leo!今天准备和大家一起分享的知识是线程池,刚好今天在看八股文,就顺带写一下并把一些实践的例子 ...
- 【Qt6】嵌套 QWindow
在上个世纪的文章中,老周简单介绍了 QWindow 类的基本使用--包括从 QWindow 类派生和从 QRasterWindow 类派生. 其实,QWindow 类并不是只能充当主窗口用,它也可以嵌 ...
- PBN衔接ILS时中间进近航段的保护区绘制方法
收到网友提问,PBN程序和ILS程序在衔接时,中间进近航段的保护区该怎么去绘制. 这个问题怎么看呢?首先起始进近航段与中间进近航段存在两种连接方式,一种是直线进近.另一种是转弯进近,两者的保护区是显著 ...
- 2020-12-25:MQ中,如何保证消息的顺序性?
福哥答案2020-12-25:[稍微详细的答案:](http://bbs.xiangxueketang.cn/question/875)生产者保证消息入队的顺序.MQ 本身是一种先进先出的数据接口,将 ...
- 2021-02-01:Redis 集群会有写操作丢失吗?
福哥答案2021-02-01: 以下情况可能导致写操作丢失:1.过期 key 被清理.2.最大内存不足,导致 Redis 自动清理部分 key 以节省空间.3.主库故障后自动重启,从库自动同步.4.单 ...
- 「P3」试下1个半月能不能水出个毕设
前言 虽然说标题上写的时间是1个半月,但是实际上,真正开始行动的时间应该1个月都没有.之前都是在公司上班没活的时候干的.现在请了个长假,专门来做毕业设计:预计5月前能做完整个毕业设计,然后劳动节放假期 ...
- Windows 安装ActiveMq5.16.6
Windows 安装ActiveMq5.16.6 前言 最近因为需要在项目中使用MQ,所以就想在我的老Windows机器上装个ActiveMq. 1. 下载安装 先到Activemq官网下载安装需要版 ...
- 适用于Linux命令的10个R函数
由于微信不允许外部链接,你需要点击文章尾部左下角的 "阅读原文",才能访问文中链接. 这篇文章将介绍 10 个不同的 Linux 命令及其 R 实现方法. 如果您有兴趣学习更多 R ...
- Python异步编程之web框架 异步vs同步 数据库IO任务压测对比
测试基本信息 主题:比较异步框架和同步框架在数据库IO操作的性能差异 python版本:python 3.8 数据库:mysql 8.0.27 (docker部署) 压测工具:locust web框架 ...
- Pytorch-如何在模型中引入可学习参数
错误实例: def init(self): self.w1 = torch.nn.Parameter(torch.FloatTensor(1),requires_grad=True).cuda() s ...