【面向打野编程】——KMP算法入门
一、问题
咱们先不管什么KMP,来看看怎么匹配两个字符串。
问题:给定两个字符串,求第二个字符串是否包含于第一个字符串中。
为了具体化,我们以 ABCAXABCABCABX 与 ABCABCABX为例。
正所谓:暴力出奇迹,枚举是真知。(大雾)先把代码敲出来再说,后面的事后面再考虑。
暴力/朴素匹配:时间复杂度O(N*M)
虽然能够得到结果,但是速(bi)度(ge)太低。多看几遍就觉得这里出现了太多无用的计算,每次匹配失败就移动一格,实在挤牙膏。
如果我们在每次匹配失败时多移动几位?
二、加速
KMP匹配:时间复杂度O(N+M)
每次移动多一点,匹配速度快一点。在已经匹配过的字符串中,上面有部分的字符串与下面字符串的前面几个元素相同。
利用已知字符,减少移动次数,比较未知字符,加快匹配速度。(KMP算法的思想)
在每次的匹配中,已匹配的字符总是与下面字符串的前面部分(前缀)相同,又与上面字符串已匹配过的部分后面(后缀)相同。可以完全匹配的字符串都在下面的字符串中(废话)。
因为只有每次匹配失败的时候才需要移动字符串,因此我们用一个fail/next/爱叫啥叫啥数组来记录移动的终点(下标)。
三、fail/next/爱叫啥叫啥数组
开辟一个fail数组,fail[i]表示在匹配word[i]失败时,i需要跳转前往的下标。
fail[i]也可表示word[0]~word[i-1]的最长公共前缀后缀长度。
如果i跑到-1则表示:word字符串不想与你说话并把你踢出了队伍。
来个循环,不断寻找自己的最长公共前缀后缀。由前面的匹配确定后面的fail数组的值,匹配失败直接使用fail数组(已确定的fail值)。
"ABCA" 最长公共前缀后缀长度为1,即"A"。
"ABCABC" 的最长公共前缀后缀长度为3,即"ABC"。
………………
void setFail(){
int i = , j = -;
while (i < wLen){
if (j == - || word[i] == word[j]) fail[++i] = ++j;
else j = fail[j];
}
}
四、动手
匹配的时候,有问题,找fail,看题目,改条件。
void setFail(){
int i = , j = -;
while (i < wLen){
if (j == - || word[i] == word[j]) fail[++i] = ++j;
else j = fail[j];
}
}
int fid(){
int i = , j = ;
while (i < tLen){
if (j == - || a[i] == word[j]) ++i, ++j;
else j = fail[j];
if (j == wLen){/*该做啥就做啥*/}
}
return -;
}
开始匹配
然后来一波入门题
POJ 3461/HDU 1686,HDU 2203,HDU 2594,HDU 1711
本渣才学疏浅,璞玉难琢,望各位神犇不吝赐(da)教(lian)。
【面向打野编程】——KMP算法入门的更多相关文章
- 「面向打野编程」iOS多线程:CGD
「面向打野编程」iOS多线程:CGD 前言 参考网络其他文章而写,渣水平,抛砖引玉. 虽然Concurrent意思为并发,但由于队列的实际效果,以下称为并行队列. 当前iPhone的CPU核心数远小于 ...
- 【初识】KMP算法入门(转)
感觉写的很好,尤其是底下的公式,易懂,链接:http://www.cnblogs.com/mypride/p/4950245.html 举个例子 模式串S:a s d a s d a s d f a ...
- 【初识】KMP算法入门
举个例子 模式串S:a s d a s d a s d f a s d 匹配串T:a s d a s d f 如果使用朴素匹配算法—— 1 2 3 4 5 6 8 9 a s d a s d a s ...
- KMP算法入门讲解
字符串匹配问题.假设文本是一个长度为$n$的字符串$T$,模板是一个长度为$m$的字符串$P$,且$m\leq n$.需要求出模板在文本中的所有匹配点$i$,即满足$T[i]=P[0],T[I+1]= ...
- KMP算法入门
学一把看毛片算法我觉得自己才能变得更加出色 明明昨天的题我都知道怎么模拟了,但是还是不会改KMP,是我学丑了 KMP是Knuth-Morris-Pratt三人设计的线性时间字符串匹配算法 nxt数组的 ...
- 【React】学习笔记(一)——React入门、面向组件编程、函数柯里化
课程原视频:https://www.bilibili.com/video/BV1wy4y1D7JT?p=2&spm_id_from=pageDriver 目录 一.React 概述 1.1.R ...
- C#面向服务编程技术WCF从入门到实战演练
一.WCF课程介绍 1.1.Web Service会被WCF取代吗? 对于这个问题阿笨的回答是:两者在功能特性上却是有新旧之分,但是对于特定的系统,适合自己的就是最好的.不能哪一个技术框架和行业标准作 ...
- 第五章 面向方面编程___AOP入门
上一篇讲了 AOP 和 OOP 的区别,这一次我们开始入门 AOP .实现面向方面编程的技术,主要分为两大类: 一是 采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行: ...
- 大型 web 前端架构设计-面向抽象编程入门
https://mp.weixin.qq.com/s/GG6AtBz6KgNwplpaNXfggQ 大型 web 前端架构设计-面向抽象编程入门 曾探 腾讯技术工程 2021-01-04 依赖反转 ...
随机推荐
- html 关于块级元素和行内元素
常用的行内元素要记住:a.span.img.input.lable.select.strong.textarea 常用的块级元素要记住:div.h1~h6.dl.ul.ol 例如在一个title中,有 ...
- Bootstrap:弹出框和提示框效果以及代码展示
前言:对于Web开发人员,弹出框和提示框的使用肯定不会陌生,比如常见的表格新增和编辑功能,一般常见的主要有两种处理方式:行内编辑和弹出框编辑.在增加用户体验方面,弹出框和提示框起着重要的作用,如果你的 ...
- HDU 5950:Recursive sequence(矩阵快速幂)
http://acm.hdu.edu.cn/showproblem.php?pid=5950 题意:给出 a,b,n,递推出 f(n) = f(n-1) + f(n-2) * 2 + n ^ 4. f ...
- PostgreSQL中使用外部表
1. 安装file_fdw 需要先安装file_fdw,一般是进到PostgreSQL的源码包中的contrib/file_fdw目录下,执行: make make install 然后进入数据库中, ...
- postgresql 热备与恢复
一. PostgreSQL热备份的过程一般为: 数据库中执行:pg_start_backup() ; 然后使用操作系统的tar或 cp命令拷贝 PostgreSQL数据文件. 数据库中执行:pg_st ...
- C/C++ 调用qsort/sort 对字符数组排序的cmp函数写法
这个问题屡次碰到解决之后再次遇到又忘记怎么弄了,这次打算彻底搞清楚. ·C 首先对所谓字符数组的排序应该是对(char)*a[]数组而非(char)a[][]进行的排序,后者是无法直接调用qsort实 ...
- Watch The Movie
Watch The Movie Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Tot ...
- Labeling Balls 分类: POJ 2015-07-28 19:47 10人阅读 评论(0) 收藏
Labeling Balls Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11893 Accepted: 3408 Descr ...
- js post提交页面
function post(URL, PARAMS) { var temp = document.createElement("form"); temp.action = URL; ...
- 2007 Asia - Nanjing F题,字典树
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=2 ...