KMP字符串匹配算法翔解❤
看了Angel_Kitty学姐的博客,我豁然开朗,写下此文:
那么首先我们知道,kmp算法是一种字符串匹配算法,那么我们来看一个例子。
比方说,现在我有两段像这样子的字符串:

分别是T和P,很明显,P比T的长度要短很多,我们要做的事情呢,就是找找T中有没有和P相同的一段。
如果按照最简单的办法来做匹配的话,我们一般是一个一个字母的来做。
像这样:

很显然,图中前面3位都是能匹配的,而第四位却不能匹配,怎么办?
这样:

我们就会将整个P字符串向右移动一格,又重新开始,从T中b处与P中第一个a处开始匹配。
如此往复,显然这样是很慢的,因为我们来考虑考虑这样一种极端的情况:

像这样,显然一位一位匹配是会做许多重复的操作的。
那么现在我们来考虑使用一下kmp算法。
怎么做呢?
首先我们需要处理一个叫做前缀表(prefix table)的东西(有些博客说是next[]数组,其实是一样的)。
什么是前缀呢?比如说,P字符串为a b a b c,那么P的前缀即为a,a b,a b a,a b a b和a b a b c共五个。

所以,做kmp算法时,我们先要把我们要搜索的那一个字符串的所有前缀都写出来。这是第一步。
好,那么第二步,我们就要将之前处理出的所有前缀当做不同的几个字符串。
然后,我们对每个这样的前缀字符串处理一下,处理出一个叫做最长公共前后缀的东西。
最长公共前后缀是比原来字符串要短的前缀与后缀最长公共部分的长度,这是什么意思呢?听起来特别拗口。

比方说,我们来看看第四个前缀字符串。很显然,它的最长前缀是a b a,最长后缀是b a b(忽略本身)。
明显这两者是不同的,所以长度取3时是不行的。那么我们取2,此时前缀是a b,后缀是a b,二者相等。
这时我们就将2称作字符串a b a b的最长公共前后缀。

如图,我们处理出了前缀表中的所有最长公共前后缀。

而在KMP算法中,前缀表里长度等于本身的那个并不需要处理,舍去,而需要在最上面添加一个-1。
(等下模拟时,其作用就显而易见了)。
现在我们已经处理好了prefix table,即-1 0 0 1 2 0。
接下来,进行第三步,将prefix table与P字符串对应,并标好下标index
1、
2、
如图,上层是index,下层是prefix。
然后,我们模拟一下KMP算法是如何利用处理好的前缀表来计算运行的。

如图,前面3位,我们还是如之前一样完美匹配,但是到了第四位,就匹配不了了,怎么办呢?
不同以往,我们不再是往右移一格,而是跳到这一位对应的prefix所指的index处,!@#$%^&*...好绕啊啊啊!
上图吧:

此时待匹配的位置的index,是不是就是之前发生错误的那个第四位所对应的prefix呢?
这样,我们便可以直接从P中第二位开始重新匹配啦!!!
p.s.忘了说了,如果prefix是-1,那么就直接向右移一格。
真是神奇讷、
不知道读者是否还记得之前提出的极端情况。

如果用KMP算法,处理好前缀表后,是不是这样:

所以 当匹配到a b时,那么就直接会跳到index为3的a处,而跳过匹配前面3个a,时间复杂度大大降低↓↓↓。
至于代码:
想看代码可以直接看我的随笔《从2017暑假到现在手打的模板》之二十三。
KMP字符串匹配算法翔解❤的更多相关文章
- KMP字符串匹配算法详解
KMP算法利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的.具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息.时间复杂度O(m+n). Next()函数 ...
- KMP字符串模式匹配详解(zz)
刚看到位兄弟也贴了份KMP算法说明,但本人觉得说的不是很详细,当初我在看这个算法的时候也看的头晕昏昏的,我贴的这份也是网上找的.且听详细分解: KMP字符串模式匹配详解 来自CSDN A_B_ ...
- BM和KMP字符串匹配算法学习
BM和KMP字符串匹配算法学习 分类: 研究与学习 字符串匹配BM(Boyer-Moore)算法学习心得 http://www.cnblogs.com/a180285/archive/2011/12/ ...
- KMP字符串模式匹配详解
KMP字符串模式匹配详解 http://www.cppblog.com/oosky/archive/2006/07/06/9486.html
- KMP字符串匹配算法理解(转)
一.引言 主串(被扫描的串):S='s0s1...sn-1',i 为主串下标指针,指示每回合匹配过程中主串的当前被比较字符: 模式串(需要在主串中寻找的串):P='p0p1...pm-1',j 为模式 ...
- KMP字符串模式匹配详解(转)
来自CSDN A_B_C_ABC 网友 KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法.简单匹配算法的时间复杂度为O(m*n);KMP匹配算法.可以证明它的时间复杂度 ...
- 【KMP】【字符串】KMP字符串匹配算法 学习笔记
一.简介 KMP是由Knuth.Morris和Prat发明的字符串匹配算法,它的时间复杂度是均摊\(O(n+m)\).其实用Hash也可以做到线性,只不过Hash存在极其微小的难以避免的冲突. ...
- 每周一算法之六——KMP字符串匹配算法
KMP是一种著名的字符串模式匹配算法,它的名称来自三个发明人的名字.这个算法的一个特点就是,在匹配时,主串的指针不用回溯,整个匹配过程中,只需要对主串扫描一遍就可以了.因此适合对大字符串进行匹配. 搜 ...
- 保证你能看懂的KMP字符串匹配算法
文章转载自一位大牛: 阮一峰原网址http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm ...
随机推荐
- 平衡二叉查找树 AVL 的实现
不同结构的二叉查找树,查找效率有很大的不同(单支树结构的查找效率退化成了顺序查找).如何解决这个问题呢?关键在于如何最大限度的减小树的深度.正是基于这个想法,平衡二叉树出现了. 平衡二叉树的定义 (A ...
- 单片机入门学习笔记8:STM32单片机使用
经常会在某个QQ群里看见某人的QQ昵称的名字"不会32绝不改名",其实无论会不会,之后名称都改了. STM32单片机在我看来就三部分组成:各部分的初始化,中断的使用,Main函数内 ...
- 为 vsftpd 启动 vsftpd:500 OOPS: SSL: cannot load RSA&nb
博主在配置ftp服务器的时候 自己生成的CA,然后认证自己的私钥文件 一切配置都是没有问题的,然后重新启动服务器 service vsftpd restart 出现以下错误 为 vsftpd 启 ...
- CERC2017 F: Faulty Factorial 简单数论题
#include <iostream> using namespace std; #define ll long long ; ll n,p,r; ll poww(ll a,ll b){ ...
- 24-webhost的配置
1-新建asp.net core空项目 2-创建setting.json文件 3- 配制Progrom类中CreateWebHostBuilder 4-获取配置的文件 5-显示结果
- Smail 中的一些点
smali中所有操作都需要经过寄存器, 本地寄存器以v开头, 参数寄存器以p开头, 非static方法中p0是this 没有-object后缀的操作指令表示操作的对象是基本类型 invoke-dire ...
- Mysql处理海量数据时的一些优化查询速度方法【转】
最近一段时间由于工作需要,开始关注针对Mysql数据库的select查询语句的相关优化方法.由于在参与的实际项目中发现当mysql表的数据量达到百万级时,普通SQL查询效率呈直线下降,而且如果wher ...
- linux命令随身记
赋予权限命令:chmod 755 * 查询进程: ps -ef |grep abc 查看含有"abc"的活动进程 ps -ef |grep -v abc 查看不含abc的活动进程 ...
- hadoop中namenode发生故障的处理方法
Namenode 故障后,可以采用如下两种方法恢复数据: 方法一:将 SecondaryNameNode 中数据拷贝到 namenode 存储数据的目录: 方法 二: 使用 -importCheckp ...
- H2数据库使用
H2数据库使用 H2数据库介绍 H2的优势: 1.h2采用纯Java编写,因此不受平台的限制. 2.h2只有一个jar文件,十分适合作为嵌入式数据库试用. 3.性能和功能的优势 H2和各数据库特征比较 ...