一、问题


  咱们先不管什么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. svn使用相关问题:eclipse插件,加锁,解锁,偷锁,更新不了,记住密码

    svn使用相关问题:eclipse插件,加锁,解锁,偷锁,更新不了,记住密码 获取锁的时候可以看下 是谁锁住了,让对方提交解锁,如果是给离职人员锁住需要使用偷锁的方式先解锁再提交偷锁处理办法:选中该文 ...

  2. Android 常用工具类之DeviceInfoUtil

    public class DeviceInfoUtil { private static WifiManager wifiManager = null; // wifi是否已连接 public sta ...

  3. ffmpeg无法接收组播流问题处理

    问题:ffmpeg无法对IP组播进行处理,表现如下 [root@os01 /]# ffprobe udp://225.0.0.2:9000 ffprobe version Copyright (c) ...

  4. VirtualBox启动虚拟机报错0x80004005

    Unable to load R3 module C:\Program Files\Oracle\VirtualBox/VBoxDD.DLL (VBoxDD): GetLastError=1790 ( ...

  5. node-webkit教程<>Native UI API 之Menu(菜单)

    node-webkit教程(6)Native UI API 之Menu(菜单)1 前言... 2 6.1  Menu 概述... 3 6.2  menu api6 6.2.1  new Menu([o ...

  6. 为ecshop红包增加”转赠”功能

    ecshop促销中使用红包激励用户购物,要想炒热活动,红包就需要有物以稀为贵的感觉.有人求有人送,这样红包之间的转赠有助于拉动第二梯队的顾客.但是如果已经把红包添加到自己的账户了怎么办?如果ecsho ...

  7. 如何扩大ImageView的点击区域

    我们在开发中会遇到,给imageview设置点击事件,但是美工切的原始图片一般在24dp左右,这个尺寸点击时会出现不灵敏的情况(点击区域太小). 解决方案: 给imageView设置  scaleTy ...

  8. 手把手教你用C++ 写ACM自动刷题神器(冲入HDU首页)

    转载注明原地址:http://blog.csdn.net/nk_test/article/details/49497017 少年,作为苦练ACM,通宵刷题的你 是不是想着有一天能够荣登各大OJ榜首,俯 ...

  9. API判断网站IP地址,国家区域

    直接访问http://api.wipmania.com/jsonp 还有经纬度

  10. sp_sys_ERPTrigger_base

    USE [GalaxyPointDB24]GO/****** Object:  StoredProcedure [dbo].[sp_zy_Process_scrap]    Script Date: ...