一眼看懂KMP匹配算法
KMP算法——快速从字符串M(母串)中找出与字符串Z(子串)匹配的子串
例1:
0 1 2 3 4 5
M:a b c a b d
Z: a b d
BF算法(最一般的算法,也叫“蛮力算法”):
将Z[0]-M[0](用“-”表示比较),如果=,则Z[1]-M[1],...直到Z[i]!=M[i],回溯
然后Z[0]-M[1],同上方法~最常见的做法,很容易理解,可是效率比较低。
KMP算法:比较过的字符段也是有信息可以利用的。
如例1,Z匹配M到 Z[2]=d != M[2]=c, 说明什么?说明前面Z[0]=M[0],Z[1]=M[1],一一对应相等。
然后需要回溯让Z[0]去和M[1]比较吗?其实没有必要
为什么? 看Z =ab d d前每个字符各不相同,既然 M=ab cxxxxxx(因为Z与M比较到d,对应的M前面的和Z一一对应相等,可以推测到M失配字符前面的字符),
BF算法是发现不匹配后让Z[0]=a回去和M[i](i=1,2,3...依次递增)比较,只有M[i]=Z[0],才有资格比较M[i+1]和Z[1],继续下一位比较下去,否则判断不等后直接就换下一位了,毫无意义。
但是我们研究了Z后发现 : Z中d前面的字符(ab)串除了Z[0](a)外没有和Z[0]相同的了,那么由于M失配字符之前的字符都是和Z对应相同的,所以推测M失配之前的字符肯定没有与Z[0]相等的,所以他们都没有必要和M[0]去比较 直接可以拿Z[0]从失配点向后比较就可以了。
好吧,我们发现Z上面还是有点信息的(重点理解红字的意思),但还是有点模糊
例2: 0 1 2 3 4 5
M:a b c a b d e a f a f
Z: a b c a b e
看例2.明显Z[5]与M[5]失配。只需要看Z就能推测出M[0]~M[4]是什么。而我们失配之后,下一次匹配比较的前提就是M[i]=Z[0](i=1,2,3....),所以看Z匹配部分
a b c a b ,推测出M对应的M[3]M[4]=ab,下次可以从M[3]开始匹配,有成功可能性。但是如果换成 如下
0 1 2 3 4 5
M:a b c a d d e a f a f
Z: a b c a d e
Z=a b c a d 虽然Z[3]=Z[0],但明显Z[4]!=Z[1],依然无法匹配,所以我们发现只有Z失配字符前呈现abxxab类型,才可从M对应ab处开始下一次监测匹配,否则M失配前的字符均无法匹配Z(如例1所示),所以也无需进行判断。
所以下一步我们只要知道Z匹配比较到第n位,那么我们通过分析Z的前n-1的字符串,分析它们的对称性,就可以判断出对应M下次开始比较的位置。
数据结构语言只是工具,关键是解决问题的思想。
这就是基本思想,具体代码网上随处可见,就不继续写了,表达可能还是不太清楚,多看两遍理解了思想,就豁然开朗了。
后面补充一种其他算法思想:
RK算法:
一个字符一个字符的比较会不会有点慢呢?
如果把n个字符的Z当成一个数z,把M的n个连续字符子串也当成一个数m。
那么如果z!=m,则M对应的该子串肯定和Z不同;反之,z=m就有很大可能相同了,只需要在一个较小的范围内逐个字符比较就好,反正又不多。
M:a b c a b d e a f a f m=abcabd
Z: a b c a b e z=abcabe
不等?m=bcabde(向后移动一位),继续比较,直到m=z,然后比较Z和M子串。其实挺快的这个方法~具体代码网上找
一眼看懂KMP匹配算法的更多相关文章
- 搞定KMP匹配算法
KMP算法介绍及实现——轻松搞定KMP匹配算法 本文介绍了字符串匹配算法中的BF算法和KMP算法.本文中KMP算法介绍部分是关于KMP算法相关文章中最简洁的一篇文章之一.下一篇将继续介绍Horspoo ...
- 4-4-串的KMP匹配算法-串-第4章-《数据结构》课本源码-严蔚敏吴伟民版
课本源码部分 第4章 串 - KMP匹配算法 ——<数据结构>-严蔚敏.吴伟民版 源码使用说明 链接☛☛☛ <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码 ...
- 数据结构——串的朴素模式和KMP匹配算法
一.朴素模式 假设我们要从主串S="goodgoogle"中找到子串T="google"的位置,步骤如下: i表示主串的当前位置下标,j表示子串的当前位置下标, ...
- c语言KMP匹配算法与字符串替换算法
一.字符串匹配算法 (1)传统匹配算法BF int Index_BF(char* S, char* T){ int i=1,j=1; while(i<=strlen(S) && ...
- KMP匹配算法 - Number Sequence
Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M ...
- KMP匹配算法
先来说一下回溯法匹配字符串: 对于主字符串有一个target_index,以target_index(不动)为起点,匹配字符串pattern的长度+target_index为终点,逐个进行比较,当发现 ...
- 一眼看懂深浅拷贝(clone)-C#
这是使用的是序列化的方式实现深拷贝 [Serializable] class Person:ICloneable { /// <summary> /// 字符串在clone 中类似于值类型 ...
- linux tar 命令 --致力于“一眼看懂,随手就用”的随笔
基本玩法: 压缩: tar -czf txt.tar.gz *.txt // 将当前目录下的所有txt文件,创建一个tar包,并用gzip算法,压缩成txt.tar.gz 文件 解压: tar -xz ...
- 一眼看懂promise async的区别
// promise方法 let p1 = new Promise((resolve,reject) => { setTimeout(() => { resolve('我是p1') },4 ...
随机推荐
- ACM HDU 2041--超级楼梯题解
超级楼梯 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- OpenLayers元素选择工具
OpenLayers的selector工具相信挺多人都没有用过,其实这个工具用处还是不少的.比如完成元素查询时,需要实现图属性联动,使用这个工具很方便.最近做项目时也使用到这个工具,使用起来确实挺方便 ...
- nginx ssl 更换问题
公司之前使用的是免费startssl证书,听说IOS 以后不信任这些免费的验证不严格的证书,公司果断购买了一个统配域名证书,其实不用貌似也没什么事,主要是提交app的时候得说明理由,被拒的可能性比较大 ...
- iOS - Regex 正则表达式
1.Regex 定义 正则表达式又称正规表示法.常规表示法(英语:Regular Expression,在代码中常简写为 regex.regexp 或 RE),计算机科学的一个概念.正则表达式使用单个 ...
- c/c++中两颗璀璨的明珠
1.指针: 函数指针做函数参数 回调函数 语法现象 意义 实现什么效果 (1).间接赋值成立的三个条件 a.两个变量 b.建立关联 c. *p-> (2).函数指针做函数参数 a.调用的角度去理 ...
- 老王讲自制RPC框架.(二.动态代理)
(#简介) 什么是动态代理?动态代理是实现阶段不关心代理是谁,而在运行阶段才指定代理对象是哪一个,动态代理在做框架方面使用非常 广泛,比如spring的aop,其核心就是采用动态代理机制,下面让我们来 ...
- linux cat 命令详解
linux cat 命令详解 http://linux.chinaunix.net/techdoc/system/2007/11/16/972467.shtml adb shell su //这个不一 ...
- Deep Learning 22:总结一些deep learning的基本知识
1.交叉熵代价函数 2.正则化方法:L1和L2 regularization.数据集扩增.dropout 3. 数据预处理 4.机器学习算法中如何选取超参数:学习速率.正则项系数.minibatch ...
- m.Tomcat使用openssl走APR通道配置单向和双向认证
引用自: http://blog.csdn.net/gtuu0123/article/details/5827800(Tomcat的SSL单向认证) http://blog.csdn.net/gtu ...
- Yii2使用教程
安装 中文文档:http://www.yiichina.com/doc/guide/2.0/start-installation 1,安装 这里我直接下载归档文件,压缩包安装了.composer各种麻 ...