从有限状态机的角度去理解Knuth-Morris-Pratt Algorithm(又叫KMP算法,”看毛片“算法)

转载请加上:http://www.cnblogs.com/courtier/p/4273193.html

  • 在开始讲这个文章前的唠叨话:

1:首先,在阅读此篇文章之前,你至少要了解过,什么是有限状态机,什么是KMP算法,因为,本文是从KMP的源头,有限状态

机来讲起的,因为,KMP就是DFA(Deterministic Finite Automaton)上简化的。

2:很多KMP的文章(有限自动机去解释的很少),写得在我看来不够好,你如果,没有良好的数学基础就很难去理解他们(比如下图),

因为,你能够理解KMP算法就已经可以入ACM新手的大门了,有很多人说一个算法就能进入ACM?来我们看看为什么叫KMP算法,很简单

这个是由三个数学家发明的,那么,我说一个算法要由三个数学家来推理,就可以说明这个分量的了。

3:有些人问,我能够举例出Next的方法来做这类题呀,我感觉太喽了,特别是计算机专业的,KMP算法还用数组慢慢移给别人看?

假设,你是面试官你是收慢慢移动的人呢?还是给出DFA的人呢?我们开始正题吧,废话有点多

( 算法导论 )

  • 我们要做的工作:

就是画出下图的有限自动机,

(帅吧,简直就是酷逼了,字符串能画成这么帅)

  • 我的方法(绝无仅有,自己通过推算摸索出来,但是,又不带数学公式的)

               1.首先,画好状态图,以上图为例,我们的输入 = {A,B,C}(因为,我们模式串只有ABC三位),构造出如下图:

2.根据上图,建立下面一张表:(就是0输入a到1等这类关系矩阵):

      1. 以0列来看,为什么是1?很简单,因为 0 输入 A 到 1,输入其他就是到0
      2. 在这里,我们得设一个X,这个X∈(0,T.len-1){其中T是字符串} 
      3. 这些固定的值就是下表的值,是不能被替换的,看了下面你就知道。
  0 1 2 3 4 5
  A B A B A C
A 1   3   5  
B   2   4    
C           6

3.在上面我们设置了一个X(这个是关键中的关键了)我们来看看怎么用?

1. 这两个X=0怎么来的呢?第一个,不用看,一定是0。第二个,我们就要看

  当前的列所代表的字母(就是列的第一个字母)跟前面的X的值所在的列中与当前字母相同的就

                                是X的值(比如,第1列的字母是B,前面一个的X是0,So,看第0列的”B ”是0),所以,第0

                                列的B的值赋值给当前列,即X=0

                            2. 再把前一个X所代表的列赋值给当前列。进入下一个。

Example 1

  X=0 X=0        
  0 1 2 3 4 5
  A B A B A C

A


1


1


3


 


5


 


B


0


2


 


4


 


 


C


0


0


 


 


 


6

Example 2

  X=0 X=0 X=1      
  0 1 2 3 4 5
  A B A B A C
A 1 1 3   5  
B 0 2 0 4    
C 0 0 0     6

4. 整张表如下:

  X=0 X=0 X=1 X=2 X=3 X=0
  0 1 2 3 4 5
  A B A B A C
A 1 1 3 1 5 1
B 0 2 0 4 0 4
C 0 0 0 0 0 6

5.画图:

  • 上面说了那么多,如果,你还不懂,还可以看我翻译的来自于Course的视频(英语不好勿怪)代码,请看我的GITHUB:

https://github.com/aliencool/Algorithm/tree/master/Searching

  • 结束语:

为什么很多人叫KMP算法叫”看毛片“算法,就因为是拼音?太LOW了这样子解释,为什么呢?因为,KMP他不回溯,每次,都是

模式串自己搞自己(你懂的),所以,才叫”看毛片“算法。

如果,你还有问题或者其他,请给我联系,请期待我下一篇可能是关于倒排索引或者基础理论的算法或者代码,谢谢,O(∩_∩)O!

时间: 2024-10-13 23:30:16

从有限状态机的角度去理解Knuth-Morris-Pratt Algorithm(又叫KMP算法,”看毛片“算法)的相关文章

模板: 字符串模式匹配 Knuth–Morris–Pratt Algorithm

Knuth–Morris–Pratt Algorithm KMP字符串模式匹配算法 模板题 Brief Introduction To be updated Algorithm To be updated Template Code #include <cstdio> #include <cstring> #define MAXN 1000005 int n,m,cnt,next[MAXN]; char s1[MAXN],s2[MAXN]; void kmp(){ next[0]=

KMP(Knuth–Morris–Pratt) Algorithm

文章 String S, 要查找的字符串 String W 重点:Get int T[] from W 用变量 c 来表示当前比较到的 W 中前面的字符,i 表示当前要处理的 T 中的 index,int[] T = new int[W.length];T[0] = -1; T[1] = 0;c=0; i=2 example:array:    a    b    a    b    c    d    a    b    a    b    a    bidx    :    0    1  

我所理解的 KMP(Knuth–Morris–Pratt) 算法

假设要在 haystack 中匹配 needle . 要理解 KMP 先需要理解两个概念 proper prefix 和 proper suffix,由于找到没有合适的翻译,暂时分别称真实前缀 和 真实后缀. 真实前缀(Proper prefix): 一个字符串中至少不包含一个尾部字符的前缀字符串.例如 "Snape" 的全部真实前缀是 “S”, “Sn”, “Sna”, and “Snap” . 真实后缀(Proper suffix): 一个字符串中至少不包含一个头部字符的后缀字符串

从逆向的角度去理解C++虚函数表

很久没有写过文章了,自己一直是做C/C++开发的,我一直认为,作为一个C/C++程序员,如果能够好好学一下汇编和逆向分析,那么对于我们去理解C/C++将会有很大的帮助,因为程序中所有的奥秘都藏在汇编中,很多问题我们从表面上无法看出到底是为什么,只要用逆向工具一分析,很快就能知道其中的所以然来.我们都知道虚函数表是放在类对象的最前面,但是很多人并不知道虚函数表的第一项存放的是什么,下面我用IDA分析一下C++的虚函数调用,从汇编的角度去理解虚函数.此文只适合具有逆向分析基础的读者,如果没有逆向分析

从需求的角度去理解Linux系列:总线、设备和驱动

笔者成为博客专家后整理以前原创的嵌入式Linux系列博文,现推出以让更多的读者受益. <从需求的角度去理解linux系列:总线.设备和驱动>是一篇有关如何学习嵌入式Linux系统的方法论文章,也是从需求的角度去理解Linux系统软件的开篇,期待此系列文章日后会是学习嵌入式Linux的标杆! 这是作者精心撰写的经验总结,希望嵌入式Linux的学习者仔细领会,多读几遍也无妨. 一.软件.面向对象.软件框架 软件是为了解决现实问题而产生的,面向对象的软件思维是解决普遍现实问题的一种有效的抽象方法,而

从需求的角度去理解Linux之一:总线、设备和驱动

这是一篇有关如何学习嵌入式Linux系统的方法论文章,也是从需求的角度去理解Linux系统软件的开篇,相信此系列文章日后会是学习嵌入式Linux的标杆! 这是作者精心撰写的经验总结,希望嵌入式Linux的学习者仔细领会,多读几遍也无妨. 转载请务必保留我们的公众号:嵌入式企鹅圈 一.软件.面向对象.软件框架 软件是为了解决现实问题而产生的,面向对象的软件思维是解决普遍现实问题的一种有效的抽象方法,而软件框架指的是用面向对象的思维去解决某种特定领域的问题而专门设计的一套行之有效的解决方案. 一般地

从认知角度去理解设计

设计并不是一味只求美感或者感觉,设计同样是一门建立在多学科基础上的科学,从认知角度来理解设计能帮助我们设计出更多尊重用户的作品,这样的设计才能经得起时间的考验,让更多用户所喜爱. 下面是我对<认知与设计——理解ui设计准则>这本书的概要与理解. 一.影响我们感知的因素     a. 经验影响感知: 我们根据经验对事物的预想:先入为主的主观印象往往影响感知,当我们带有    不同的主观感受去观察同一张图片时会看到不同的东西 我们的认知框架:认知框架即是不断置身的各种环境在我们心智中建立起开模式,

以吃货的角度去理解云计算中On-Premise、IaaS、PaaS和SaaS

了解云计算的一定都听过四个“高大上”的概念:On-Premise(本地部署),IaaS(基础设施及服务).PaaS(平台即服务)和SaaS(软件即服务),这几个术语并不好理解.不过,如果你是个吃货,还喜欢汉堡,那这个问题就好解决了! 如果我想吃汉堡,有几种方法呢? 1.自己买材料自己做 准备烤箱,准备火腿,准备面粉,准备青菜,然后自己和面,加材料,加热等等.其要求动手能力比较强,比较难做,但是,您可以根据自己的口味,做出符合自己味道的汉堡.这就是On-Premise(本地部署). 典型代表:物理

从信息熵角度去理解问题

信息是个很抽象的概念.人们常常说信息很多,或者信息较少,但却很难说清楚信息到底有多少.比如一本五十万字的中文书到底有多少信息量.直到1948年,香农提出了“信息熵”的概念,才解决了对信息的量化度量问题.三国真人娱乐城 一条信息的信息量大小和它的不确定性有直接的关系.比如说,我们要搞清楚一件非常非常不确定的事,或是我们一无所知的事情,就需要了解大量的信息.相反,如果我们对某件事已经有了较多的了解,我们不需要太多的信息就能把它搞清楚.所以,从这个角度,我们可以认为,信息量的度量就等于不确定性的多少.