从有限状态机的角度去理解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等这类关系矩阵):
- 以0列来看,为什么是1?很简单,因为 0 输入 A 到 1,输入其他就是到0
- 在这里,我们得设一个X,这个X∈(0,T.len-1){其中T是字符串}
- 这些固定的值就是下表的值,是不能被替换的,看了下面你就知道。
| 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 |

- 上面说了那么多,如果,你还不懂,还可以看我翻译的来自于Course的视频(英语不好勿怪)代码,请看我的GITHUB:
https://github.com/aliencool/Algorithm/tree/master/Searching
- 结束语:
为什么很多人叫KMP算法叫”看毛片“算法,就因为是拼音?太LOW了这样子解释,为什么呢?因为,KMP他不回溯,每次,都是
模式串自己搞自己(你懂的),所以,才叫”看毛片“算法。
如果,你还有问题或者其他,请给我联系,请期待我下一篇可能是关于倒排索引或者基础理论的算法或者代码,谢谢,O(∩_∩)O!
从有限状态机的角度去理解Knuth-Morris-Pratt Algorithm(又叫KMP算法)的更多相关文章
- 我所理解的 KMP(Knuth–Morris–Pratt) 算法
假设要在 haystack 中匹配 needle . 要理解 KMP 先需要理解两个概念 proper prefix 和 proper suffix,由于找到没有合适的翻译,暂时分别称真实前缀 和 真 ...
- 从逆向的角度去理解C++虚函数表
很久没有写过文章了,自己一直是做C/C++开发的,我一直认为,作为一个C/C++程序员,如果能够好好学一下汇编和逆向分析,那么对于我们去理解C/C++将会有很大的帮助,因为程序中所有的奥秘都藏在汇编中 ...
- 从需求的角度去理解Linux系列:总线、设备和驱动
笔者成为博客专家后整理以前原创的嵌入式Linux系列博文,现推出以让更多的读者受益. <从需求的角度去理解linux系列:总线.设备和驱动>是一篇有关如何学习嵌入式Linux系统的方法论文 ...
- 字符串匹配算法--KMP字符串搜索(Knuth–Morris–Pratt string-searching)C语言实现与讲解
一.前言 在计算机科学中,Knuth-Morris-Pratt字符串查找算法(简称为KMP算法)可在一个主文本字符串S内查找一个词W的出现位置.此算法通过运用对这个词在不匹配时本身就包含足够的信息 ...
- 以吃货的角度去理解云计算中On-Premise、IaaS、PaaS和SaaS
了解云计算的一定都听过四个“高大上”的概念:On-Premise(本地部署),IaaS(基础设施及服务).PaaS(平台即服务)和SaaS(软件即服务),这几个术语并不好理解.不过,如果你是个吃货,还 ...
- Android AsyncTask完全解析,带你从源码的角度彻底理解
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11711405 我们都知道,Android UI是线程不安全的,如果想要在子线程里进 ...
- [转]Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
Android事件分发机制 该篇文章出处:http://blog.csdn.net/guolin_blog/article/details/9097463 其实我一直准备写一篇关于Android事件分 ...
- Android 进阶学习:事件分发机制全然解析,带你从源代码的角度彻底理解(上)
http://blog.csdn.net/guolin_blog/article/details/9097463 事实上我一直准备写一篇关于Android事件分发机制的文章,从我的第一篇博客開始,就零 ...
- 从源码角度深入理解Toast
Toast这个东西我们在开发中经常用到,使用也很简单,一行代码就能搞定: 1: Toast.makeText(", Toast.LENGTH_LONG).show(); 但是我们经常会遇到这 ...
随机推荐
- 【转】asp.net mvc webapi+angular.js案例
参考地址:http://www.mamicode.com/info-detail-892383.html 大家好,本文用一个简单的demo演示AngularJS在MVC中的使用,在学习这个demo之前 ...
- 关于数据表命名为mysql保留的时候的操作
今天操作数据表的时候,发现order数据表无法进行操作,必须加上反单引号才能进行操作,查了一下原因: 反引号是用来区别mysql关键字的,比如,如果你有一个表名叫select,你就必须写成`selec ...
- js中的循环语句
js中的循环语句可分为三种:1.while:2.do……while:3.for. while的语法为 while (exp) { //statements;} var a=1,b=0; whil ...
- java对象的内存分配
(1) 寄存器(register).这是最快的保存区域,这是主要由于它位于处理器内部.然而,寄存器的数量十分有限,所以寄存器是需要由编译器分配的.我们对此没有直接的控制权,也不可能在自己的程序里找到寄 ...
- oracle 按某个字段查询重复数据
/* 手机号为重复的会员,获取其最大会员id,对应的会员信息 */ SELECT * FROM MEMBER a WHERE a.member_id IN ( SELECT MAX(member_id ...
- C# XML流操作简单实例
这里我们先介绍操作XML文件的两个对象:XmlTextReader和XmlTextWriter打开和读取Xml文件使用到的对象就是XmlTextReader对象.下面的例子打开了与程序在同一路径下的一 ...
- C#析构函数,类运行结束后运行
public class Students { //创建对像时使用 public Students(string name, int age, char gender, int englist, in ...
- 在同个类中non-const插入const来减少重复
class A { private: std::string a; public: A(std::string b) :a(b){} const char& operator[](int b) ...
- eclipse python开发环境搭建
eclipse python开发环境搭建[非原创] 1.在www.eclipse.org官网下载Eclipse Classic 4.2.2,Win7 64位下载eclipse-SDK-4.2.2-wi ...
- C#Mysql数据库爆破源码
声明: 代码仅供学习参考使用!开启了一个子线程,进行爆破! 速度不是很快,代码不是很规范,希望大牛不要喷我! c#控制台程序,需要引用MySql.Data.dll 默认用户名: root密码字典: p ...