一、问题


  咱们先不管什么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算法入门的更多相关文章

  1. 「面向打野编程」iOS多线程:CGD

    「面向打野编程」iOS多线程:CGD 前言 参考网络其他文章而写,渣水平,抛砖引玉. 虽然Concurrent意思为并发,但由于队列的实际效果,以下称为并行队列. 当前iPhone的CPU核心数远小于 ...

  2. 【初识】KMP算法入门(转)

    感觉写的很好,尤其是底下的公式,易懂,链接:http://www.cnblogs.com/mypride/p/4950245.html 举个例子 模式串S:a s d a s d a s d f a  ...

  3. 【初识】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 ...

  4. KMP算法入门讲解

    字符串匹配问题.假设文本是一个长度为$n$的字符串$T$,模板是一个长度为$m$的字符串$P$,且$m\leq n$.需要求出模板在文本中的所有匹配点$i$,即满足$T[i]=P[0],T[I+1]= ...

  5. KMP算法入门

    学一把看毛片算法我觉得自己才能变得更加出色 明明昨天的题我都知道怎么模拟了,但是还是不会改KMP,是我学丑了 KMP是Knuth-Morris-Pratt三人设计的线性时间字符串匹配算法 nxt数组的 ...

  6. 【React】学习笔记(一)——React入门、面向组件编程、函数柯里化

    课程原视频:https://www.bilibili.com/video/BV1wy4y1D7JT?p=2&spm_id_from=pageDriver 目录 一.React 概述 1.1.R ...

  7. C#面向服务编程技术WCF从入门到实战演练

    一.WCF课程介绍 1.1.Web Service会被WCF取代吗? 对于这个问题阿笨的回答是:两者在功能特性上却是有新旧之分,但是对于特定的系统,适合自己的就是最好的.不能哪一个技术框架和行业标准作 ...

  8. 第五章 面向方面编程___AOP入门

    上一篇讲了 AOP 和 OOP 的区别,这一次我们开始入门 AOP .实现面向方面编程的技术,主要分为两大类: 一是 采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行: ...

  9. 大型 web 前端架构设计-面向抽象编程入门

    https://mp.weixin.qq.com/s/GG6AtBz6KgNwplpaNXfggQ 大型 web 前端架构设计-面向抽象编程入门 曾探 腾讯技术工程 2021-01-04   依赖反转 ...

随机推荐

  1. sql基础查询

    2.1 指定使用中的资料库 一个资料库伺服器可以建立许多需要的资料库,所以在你执行任何资料库的操作前,通常要先指定使用的资料库.下列是指定资料库的指令: 如果你使用「MySQL Workbench」这 ...

  2. linux设备驱动归纳总结(三):4.ioctl的实现【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-59419.html linux设备驱动归纳总结(三):4.ioctl的实现 一.ioctl的简介: 虽 ...

  3. python编码:gbk编码与解码

    从RF输入的中文会进行unicode编码:u'\u6587\u4ef6\u5230\u8fbe\u6210\u529f' 从orc数据库查询到的中文会进行gbk编码得到ASCII:'\xce\xc4\ ...

  4. Array JSON

    Tool: Online jsonviewer JSON: JavaScript Object Notation. JSON is a syntax for storing and exchangin ...

  5. bodybuilding

    增大肌肉块的14大秘诀:大重量.低次数.多组数.长位移.慢速度.高密度.念动一致.顶峰收缩.持续紧张.组间放松.多练大肌群.训练后进食蛋白质.休息48小时.宁轻勿假. 1. 大重量.低次数:健美理论中 ...

  6. svn down代码的时候提示“由于目标计算机积极拒绝,无法连接”

    如上图所示: 原因1:svn没有启动成功 原因2:防火墙没有svn的端口号3690 解决方法: 1.启动svn服务 svnserve -d -r svn路径   例如:svnserve -d -r / ...

  7. combobox中动态加入几个checkbox,实现下拉框多选

    combobox中动态加入几个checkbox,实现下拉框多选,将一个checkbox选中时其内容就会在combobox中显示出来,将另一个checkbox选中时其内容会跟在第一个checkbox的内 ...

  8. JSTL.带标签体的标签,方法和例子

    1. 实现 forEach 标签: 两个属性: items(集合类型, Collection), var(String 类型) doTag: 遍历 items 对应的集合 把正在遍历的对象放入到 pa ...

  9. poj1703 Lost Cows

    给定集合{1,2,...,n}的一个置换,指定每个位置上在其左方且比其小的数的个数,求该置换. 这题我目前还只会O(n^2)的做法. 以后再用更高效的算法解决. http://poj.org/prob ...

  10. mysql一些常用命令总结

    mysql时间戳转日期格式SELECT FROM_UNIXTIME(add_time,'%Y-%m-%d %H:%i:%s') FROM `wh5_username` where id=23; 按in ...