本文主要参考了https://mp.weixin.qq.com/s/rbaPmBejID8-rYui35Snrg的表述,加上部分自己的理解

学习任何算法都要了解该算法解决什么问题?我们看看KMP算法主要解决什么问题。我们举一个例子,已知字符串1(ABCABBABAABBA)中查找字符串2(ABCAAB)是否存在,如果存在,字符串2在字符串1中的起始位置是多少?

对于上面这个列子,我们很快就可以回答出来字符串2(ABCAAB)在字符串1中存在,起始位置为5(假设从0开始)

暴力匹配:

不考虑任何效率的问题,当然就是从头到尾比较过去了,比如:

ABCABBABAABBA

ABCAAB→

比较下来,发现从第4个字符开始不同了,那没办法,说明前5个字符不是我们想要的字串,接下来我们就让字符串往前拱一步,继续比较:

ABCABBABAABBA

ABCAAB→

这一轮更惨,第一个就栽了,没关系,继续死磕往前拱:

ABABCBABAABBA

ABCAAB→

这一轮也不咋滴,比较到第3个就歇菜了。只要我们有毅力,这个过程坚持不懈,总能找到(或者找不到)答案。

暴力求解算法的复杂度为:假设长字符串为n,短字符串为m,在最极端的情况下(只有最后m个字符才互相匹配)我们需要走n-m轮,每一轮需要匹配m次,时间复杂度为O(nm)

现在的问题是:有没有更快的方法来找到匹配的字串呢?

KMP算法

KMP算法的核心意思就是:当我们发现一次比较下来字串没有完全匹配的情况下,下一次的比较也许可以不止往前拱一步,也许可以拱N步,关键是,究竟可以拱几步呢?

搞清楚这个问题前,先来搞清楚一个关键信息:“部分匹配值”,官方的解释太啰嗦了,我掰开了揉碎了讲给你听,就是这样:将我们要匹配的字串写出来,写两遍:

ABCAAB→

←ABCAAB

看到了吧,我们让他们一个向左一个向右,相向而行。算一下上一行的右边跟下一行的左边,最多能有几个字符是重合的(注意上一行的首字符不参与这个游戏,否则每个字串都是从头配到尾,就没意思了),这个数值N就是字串ABAAB的所谓部分匹配值,当然,你会发现此时N等于2,因为:

后缀

ABCAAB

ABCAAB

前缀

下边的字串再往前走,再也找不到更多的重合的字符了,因此字串"ABAAB"的部分匹配值为2,记为:

ABCAAB

2

来,继续算部分匹配值,接下来缩短一点,将最右边的B去掉,来看ABAA的部分匹配值:

ABCAA

ABCAA

显而易见,字串"ABAA"的部分匹配值是1,记为:

ABCAAB

1 2

不断重复上述过程,将每一个字串的“部分匹配值”都算出来,就是所谓的部分匹配表,如下所示。

ABCAAB

00 01 12

好了,花开两朵各表一枝,说回刚刚提到的问题:发现不匹配之后,究竟要向右拱几步呢?答案是:可以往前拱 (N-x) 步。N指的是匹配的字符数,x是部分匹配值,现在我们再把刚开始的步骤再做一遍:

ABCABBABAABBA

ABCAAB→

比较下来发现有3个字符匹配,此时N=4,查表得知ABCA的部分匹配值x=1,因此我们此时可以往前拱 (4-1)步,接下来比较:

ABCABBABAABBA

ABCAAB→

  我想大家心中一定有这样一个疑问,为什么可以这样子移动,这样子移动不会漏掉匹配数据吗?

上面一行的红色字体ABCA的最后一个A其实就是ABCA的最长后缀

ABCABBABAABBA

        ABCAAB→

下面一行的红色字体的ABCA的第一个字符A其实就是最长前缀

我们移动的目的就是要让最长后缀(A)与最长的前缀(A)重合,也就是让两头的部分匹配的区段重合在一起

为什么可以这样子移动?

因为我们知道ABCA前后缀匹配部分只有A,也就是说ABCABBABAABBA的前缀AB与ABCA的后缀CA是不匹配的。

如果我们把小字符串ABCAAB中的A移动到与ABCABBABAABBA中A前面任何一个位置,比如C位置得到的上下字符一定不匹配,因为它们公共部分只有A

ABCABBABAABBA

     ABCAAB

         

你发现,此时我们就跳过了一些比较循环,让我们整个算法的效率得到极大的提升。其实KMP算法的核心,就是充分利用比较过的未能匹配的字串的信息,而不是一股脑将他们丢弃。

字符串匹配算法系列一:KMP算法原理的更多相关文章

  1. 字符串匹配--kmp算法原理整理

    kmp算法原理:求出P0···Pi的最大相同前后缀长度k: 字符串匹配是计算机的基本任务之一.举例,字符串"BBC ABCDAB ABCDABCDABDE",里面是否包含另一个字符 ...

  2. 常用算法3 - 字符串查找/模式匹配算法(BF & KMP算法)

    相信我们都有在linux下查找文本内容的经历,比如当我们使用vim查找文本文件中的某个字或者某段话时,Linux很快做出反应并给出相应结果,特别方便快捷! 那么,我们有木有想过linux是如何在浩如烟 ...

  3. 字符串匹配算法——BF、KMP、Sunday

    一:Brute force 从源串的第一个字符开始扫描,逐一与模式串的对应字符进行匹配,若该组字符匹配,则检测下一组字符,如遇失配,则退回到源串的第二个字符,重复上述步骤,直到整个模式串在源串中找到匹 ...

  4. KMP算法原理

    前几天在看数据结构与算法,里面提到过kmp算法,一个超级经典的字符串匹配算法.虽然网上有一大堆关于kmp算法的介绍文章,但是我看过之后还是“不明觉厉”.所以打算自己写写,大家一起学习吧. 一.关于KM ...

  5. 搜索模式| 系列2——KMP算法

    给定一个文本txt [0..n-1]和一个模式pat [0..m-1],写一个搜索函数search(char pat [],char txt []),在txt中打印所有出现的pat [] [].可以假 ...

  6. 讲不明白自杀系列:KMP算法

    算法:KMP排序 算法分析 KMP算法是一种快速的模式匹配算法.KMP是三位大师:D.E.Knuth.J.H.Morris和V.R.Pratt同时发现的,所以取首字母组成KMP. 少部分图片来自孤~影 ...

  7. 字符串匹配算法之BF(Brute-Force)算法

    BF(Brute-Force)算法 蛮力搜索,比较简单的一种字符串匹配算法,在处理简单的数据时候就可以用这种算法,完全匹配,就是速度慢啊. 基本思想 从目标串s 的第一个字符起和模式串t的第一个字符进 ...

  8. 字符串(2)KMP算法

    给你两个字符串a(len[a]=n),b(len[b]=m),问b是否是a的子串,并且统计b在a中的出现次数,如果我们枚举a从什么位置与匹配,并且验证是否匹配,那么时间复杂度O(nm), 而n和m的范 ...

  9. 字符串匹配算法BF和KMP总结

    背景 来看一道leetcode题目: Implement strStr(). Returns the index of the first occurrence of needle in haysta ...

随机推荐

  1. CI在nginx环境下去掉url中的index.php

    在nginx环境下CI框架默认URL规则访问不了,出现500错误,如: http://blog.php230.com/index.php/keywords 今天在服务器配置CI框架环境时,去除URL中 ...

  2. 【bzoj3884】上帝与集合的正确用法 扩展欧拉定理

    题目描述 根据一些书上的记载,上帝的一次失败的创世经历是这样的: 第一天, 上帝创造了一个世界的基本元素,称做“元”. 第二天, 上帝创造了一个新的元素,称作“α”.“α”被定义为“元”构成的集合.容 ...

  3. HDU 5307 He is Flying ——FFT

    卷积的妙用,显然我们可以求出所有符合条件的右端点的和,然后减去左端点的和. 就是最后的答案.然后做一次前缀和,然后就变成了统计差是一个定值的情况. 令$A(s[i])++$ $B(s[i])+=i$ ...

  4. BZOJ3999 [TJOI2015]旅游 【树剖 + 线段树】

    题目 为了提高智商,ZJY准备去往一个新世界去旅游.这个世界的城市布局像一棵树.每两座城市之间只有一条路径可 以互达.每座城市都有一种宝石,有一定的价格.ZJY为了赚取最高利益,她会选择从A城市买入再 ...

  5. git下载其他人分支的代码

    1. 在工作空间,右键,打开Git Bash 2. clone主分支的代码(即下载主分支代码的过程) 执行命令: git clone xxx.git 3. 进入工程目录 cd   xxx 4. 切换到 ...

  6. 【转】Linux C函数库参考

    asctime(将时间和日期以字符串格式表示)clock(取得进程占用CPU的大约时间)ctime(将时间和日期以字符串格式表示)difftime(计算时间差距)ftime(取得目前的时间和日期)ge ...

  7. 【11】react 之 flux

    Flux 是 Facebook 使用的一套前端应用的架构模式.React 标榜自己是 MVC 里面 V 的部分,那么 Flux 就相当于添加 M 和 C 的部分. 1.1.  Flux介绍 Flux并 ...

  8. C#、.Net学习资料免注册下载基地。。。

    原文发布时间为:2008-11-28 -- 来源于本人的百度文章 [由搬家工具导入] http://club.topsage.com/forumdisplay.php?fid=121&filt ...

  9. 利用GridView控件导出其他文件(导出Excel,导出Word文件)

    原文发布时间为:2008-10-16 -- 来源于本人的百度文章 [由搬家工具导入] // 注意,在Visual Studio2005平台下,如果使用GridView导出文件,      //就必须重 ...

  10. transform与position:fixed的那些恩怨

    1. 前言 在写这篇文章之前,我理解的fixed元素是这样的:(摘自CSS布局基础) 固定定位与absolute定位类型类似,但它的相对移动的坐标是视图(屏幕内的网页窗口)本身.由于视图本身是固定的, ...