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匹配算法的更多相关文章

  1. 搞定KMP匹配算法

    KMP算法介绍及实现——轻松搞定KMP匹配算法 本文介绍了字符串匹配算法中的BF算法和KMP算法.本文中KMP算法介绍部分是关于KMP算法相关文章中最简洁的一篇文章之一.下一篇将继续介绍Horspoo ...

  2. 4-4-串的KMP匹配算法-串-第4章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第4章  串 - KMP匹配算法 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码 ...

  3. 数据结构——串的朴素模式和KMP匹配算法

    一.朴素模式 假设我们要从主串S="goodgoogle"中找到子串T="google"的位置,步骤如下: i表示主串的当前位置下标,j表示子串的当前位置下标, ...

  4. c语言KMP匹配算法与字符串替换算法

    一.字符串匹配算法 (1)传统匹配算法BF int Index_BF(char* S, char* T){ int i=1,j=1; while(i<=strlen(S) && ...

  5. KMP匹配算法 - Number Sequence

    Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M ...

  6. KMP匹配算法

    先来说一下回溯法匹配字符串: 对于主字符串有一个target_index,以target_index(不动)为起点,匹配字符串pattern的长度+target_index为终点,逐个进行比较,当发现 ...

  7. 一眼看懂深浅拷贝(clone)-C#

    这是使用的是序列化的方式实现深拷贝 [Serializable] class Person:ICloneable { /// <summary> /// 字符串在clone 中类似于值类型 ...

  8. linux tar 命令 --致力于“一眼看懂,随手就用”的随笔

    基本玩法: 压缩: tar -czf txt.tar.gz *.txt // 将当前目录下的所有txt文件,创建一个tar包,并用gzip算法,压缩成txt.tar.gz 文件 解压: tar -xz ...

  9. 一眼看懂promise async的区别

    // promise方法 let p1 = new Promise((resolve,reject) => { setTimeout(() => { resolve('我是p1') },4 ...

随机推荐

  1. Subtitute

    报表导出到Excel时,日期已经被格式化,有时候日期格式带星期几,比方说"2016-12-30 星期五",或者是"2016/12/30 星期五". 我不想要星期 ...

  2. EXCLE使用中常用函数和公式

    1.查找重复项 IF(COUNTIF(A:A,A1)>1"重复""") 或者 IF(COUNTIF($A$1:$A$100,A1)=1,"&qu ...

  3. java.lang.ExceptionInInitializerError /NoClassDefFoundError: [Lorg/hibernate/engine/FilterDefinition;

    java.lang.ExceptionInInitializerError at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Nati ...

  4. 《与小卡特一起学Python》Code4 GUI easygui的使用

    EasyGui是基于TKinter的,所以可以跨平台使用. 使用方法很简单,下载之后解压把easygui.py放到python安装目录下的lib/site-packages/下面即可 import e ...

  5. android面试题

    1. 请描述一下Activity 生命周期. 答: 如下图所示.共有七个周期函数,按顺序分别是: onCreate(), onStart(), onRestart(), onResume(), onP ...

  6. 回调函数及数组中sort()方法实现排序的原理

    1.回调函数:把一个方法A当一个参数值传递到另外一个函数B中,在B执行的过程当中我们随时根据需求让A方法执行:   什么是回调 :它是异步编程基本的方法,需要异步处理的时候一般采用后续传递的方式,将后 ...

  7. J2EE版本

    Different versions of JEE: Note: JPE (Java Professional Edition) project announced in May 1998 at Su ...

  8. appium 常用API

    ''.appium api第二弹 锋利的python,这是初稿,2015/1/5 如有错误的地方,请同学们进行留言,我会及时予以修改,尽量整合一份ok的api 作者:Mads Spiral QQ:79 ...

  9. 转:图解Git[强烈推荐]

    https://my.oschina.net/xdev/blog/114383 再次感谢原著作者和中文翻译者. 此页图解git中的最常用命令.如果你稍微理解git的工作原理,这篇文章能够让你理解的更透 ...

  10. iOS开发 iOS9横屏后状态栏隐藏处理

    - (BOOL)prefersStatusBarHidden { return NO; }