[知识点]KMP算法
// 此博文为迁移而来,写于2015年5月24日,不代表本人现在的观点与看法。原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w1iw.html
UPDATE(20200316):重写介绍(五年前好像什么都没写一样)。
1、前言
好吧我得承认这东西应该是早就要会了的。。。虽然感觉上用的不多,但是当我开始接触AC自动机的时候,发现这是一个很必要的知识点,所以今天来讲一讲。
然而有一个问题了——为什么我一直没有搞懂就是因为许多许多次我看网上的一些文章就发现总是弄得很复杂,所以我推荐大家直接看代码,更容易弄懂。反正我就这么明白了。在AC自动机明白之后,将会有更详细地阐述。
2、介绍
KMP算法,是在普通字符串匹配算法的基础上改进的算法,核心在于:利用每次匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。首先我们先看看普通匹配算法的思路:假设读入a, b两个字符串,a为主串,b为模式串。从a的第一位起,与b的第一位起逐位匹配,直到匹配到模式串串尾。如果出现不匹配情况,则退出该次匹配,从a的第二位起,与b的第一位起逐位匹配,以此类推,即最坏匹配复杂度为O(a.len * b.len)。
KMP算法引入一个新的数组:fail数组,表示b的第i位起的子串与b本身串的最长前缀长度。例如:

同样地,你也可以理解为表示b的前i位子串的公共前后缀长度(即前缀和后缀相同)。
预处理出fail数组的意义是什么?前面提到了,每次匹配失败,我们都需要从主串第一位重新来过。

再来看一个例子,如图所示,在匹配过程中匹配到第6位时,我们发现匹配失败了;而已匹配上的前5位,其第5位的fail值为3,表示前5位的公共前后缀长度为3,也就是说,[3, 5]子串和[1, 3]子串是一致的,那我们也就不再需要对这一段进行一一匹配了,从而直接从a的第5+1=6位和b的第3+1=4位开始匹配。

以此类推,可以理解为b串自身整体右移,使其与a串匹配,故时间复杂度约为O(a.len + b.len),大幅降低。
3、代码
#include <bits/stdc++.h>
using namespace std; #define MAXN 100005 int la, lb, fail[MAXN];
char a[MAXN], b[MAXN]; int main() {
cin >> a + >> b + ;
la = strlen(a + ), lb = strlen(b + );
fail[] = -;
for (int i = , x = -; i <= lb; i++) {
while (x >= && b[x + ] != b[i]) x = fail[x];
fail[i] = ++x;
}
for (int i = , x = ; i <= la; i++) {
while (x >= && b[x + ] != a[i]) x = fail[x];
if (++x == lb) cout << i - lb + , exit();
}
cout << "N/A";
return ;
}
[知识点]KMP算法的更多相关文章
- KMP算法简明扼要的理解
KMP算法也算是相当经典,但是对于初学者来说确实有点绕,大学时候弄明白过后来几年不看又忘记了,然后再弄明白过了两年又忘记了,好在之前理解到了关键点,看了一遍马上又能理解上来.关于这个算法的详解网上文章 ...
- KMP算法简明法则
KMP算法也算是相当经典,但是对于初学者来说确实有点绕,大学时候弄明白过后来几年不看又忘记了,然后再弄明白过了两年又忘记了,好在之前理解到了关键点,看了一遍马上又能理解上来.关于这个算法的详解网上文章 ...
- 串匹配问题 (KMP算法) 详解
串这个概念对于我们学到现在的水平来说应该是经历颇丰了,因为在C语言中我们所用到的"串"知识是在字符串那里,有了这个概念,我们再去学习串就相对而言轻松多了. 那么,现在来介绍一下字符 ...
- 简单有效的kmp算法
以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...
- KMP算法
KMP算法是字符串模式匹配当中最经典的算法,原来大二学数据结构的有讲,但是当时只是记住了原理,但不知道代码实现,今天终于是完成了KMP的代码实现.原理KMP的原理其实很简单,给定一个字符串和一个模式串 ...
- 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)
前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...
- KMP算法实现
链接:http://blog.csdn.net/joylnwang/article/details/6778316 KMP算法是一种很经典的字符串匹配算法,链接中的讲解已经是很明确得了,自己按照其讲解 ...
- 数据结构与算法JavaScript (五) 串(经典KMP算法)
KMP算法和BM算法 KMP是前缀匹配和BM后缀匹配的经典算法,看得出来前缀匹配和后缀匹配的区别就仅仅在于比较的顺序不同 前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从 左到右 后缀匹配 ...
- 扩展KMP算法
一 问题定义 给定母串S和子串T,定义n为母串S的长度,m为子串T的长度,suffix[i]为第i个字符开始的母串S的后缀子串,extend[i]为suffix[i]与字串T的最长公共前缀长度.求出所 ...
随机推荐
- Java集合源码学习(五)几种常用集合类的比较
这篇笔记对几个常用的集合实现,从效率,线程安全和应用场景进行综合比较. >>ArrayList.LinkedList与Vector的对比 (1)相同和不同都实现了List接口,使用类似.V ...
- elasticsearch入门
到 https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.6.0.zip 下载最新包: 启动: ./elast ...
- 运用ASMIOSTAT脚本监控asm disk磁盘性能
1,脚本作用: 类似于OS的iostat检查磁盘的I/O性能,ASMIOSTAT 脚本用来检查ASM磁盘的性能, 2,下载AMSIOSTAT脚本http://files.cnblogs.com/fil ...
- java 杂物间 (二) Spring Web
需要明确记住的继承关系
- [QCon] Scrum阅读随想
最近从群里面下载到几篇文章,看到QCon出来的相关文章,觉得都写的很不错,都是一些个大公司的非常好的方法 QCon:是为团队领导者.架构师.项目经理和高级软件开发人员量身打造的企业软件开发大会,其 ...
- 免费电子书:Azure Web Apps开发者入门
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:之前介绍过微软正在逐步出版一个名为Azure Essential的入门系列教程,最近刚 ...
- 汇编学习(四)——算术运算程序
(一)跳转指令 一.无条件跳转指令(不管标志寄存器,执行到这句直接跳转) 1.段内直接跳转指令 (1)指令格式: JMP SHORT short_label; IP<--IP+DB,即代码直接跳 ...
- Hibernate 延迟加载
一.什么是延迟加载? 延迟加载是指当应用程序想要从数据库获取对象时(在没有设置lazy属性值为false),Hibernate只是从数据库获取符合条件的对象的OId从而生成代理对象,并没有加载出对象访 ...
- linux安装配置SVN并设置钩子
安装说明 系统环境:CentOS-6.3安装方式:yum install (源码安装容易产生版本兼容的问题)安装软件:系统自动下载SVN软件 检查已安装版本 #检查是否安装了低版本的SVN 1 rpm ...
- HDU 3926 图的同构
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3926 题意:给定2个顶点度最大为2的无向图.问你这2个无向图是否同构. 思路: 1.最大度为2.说明这 ...