KMP算法推导
来源:互联网 发布:淘宝名字大全2016款女 编辑:程序博客网 时间:2024/06/16 11:44
一个问题
有一个主串S1,一个子串S2,如何判断主串S1中是否存在子串S2 ?
朴素模式匹配算法
我们举个例子
主串S1:abcdefgab
子串S2:abcdex
朴素模式匹配法的原理:
设i,j 分别表示主串S1与子串S2上的第i,j 个元素。i,j 均初始化为1
1. S1的第i个元素 与 S2的第j个元素进行对比,如果相同,执行步骤 2 。如果不同,执行步骤 3
2. i++, j++ , 重复步骤 1
3. j = 1 , 执行步骤 1
。。。
直到找到子串 或 主串被遍历
观察朴素模式匹配过程:
1.
2.
3.
4.
5.
6.
朴素模式匹配的步骤为1~6
我们观察一下子串S2:abcdex
,首字符a
与后边的bcdex
中的字符均不相等
当第1步前边的abcde
已匹配,而S1中的f 与 S2中的f 不匹配,执行了第2步
由于之前b已经与S1中的第二个元素匹配,b与a不相等,则没必要有第二步
同理,步骤3 4 5均不必要
或许会觉得其实也没什么。。。
假如主串为:00000000000000000000000000000000000000000000000000000000001
子串为:00000000000000001
朴素模式匹配法将会耗费大量时间,效率低
KMP匹配算法
正如上边所说,我们应该省去一些不必要的匹配,这也正是KMP算法产生的根本原因
我们可以在发现f不与x匹配时,由步骤1直接跳到步骤6
因为子串abcdex
前边的abcde
中,a与他们均不相同
假如子串后遍也有a呢?
我么再来看个例子:
主串S1:abcabcabc
子串S2:abcabx
朴素模式匹配法步骤如下:
1.
2.
3.
4.
5.
6.
我们可以跳过步骤2 和步骤3 ,原因就不多说了
然后观察步骤4 步骤5
在子串中第一位的a与第四位的a相等,第二位与第五位同为b
由于步骤1中已经匹配了前5 个元素,所以步骤4 步骤5 也可以省去,不需要再比较了
因为肯定也是相等的(之前比较过了,还判断什么)
最后结果:只需要步骤1 与 步骤6
一个发现
经过一番推到后的匹配步骤中
- 在步骤1 时,主串的下标i 为6
- 在步骤6 中,主串的下标i 还是6
在朴素模式匹配中,主串的下标i 是不断地回溯的
经过我们的推导,发现这种回溯是不必要的
我们的KMP算法就是为了让这些没必要的回溯不发生
如何实现KMP算法呢?
既然主串的i 不需要回溯,那么我们就要考虑子串下标j 的变化了
在我们之前的两个例子中,屡屡提到子串中首字符与后边字符的比较
如果发现有相等,则j 就会有不同的变化
所以j 的变化与主串无关,而与子串中的重复有关
有什么关系呢?
比如第一个例子中,子串为:abcdex
没有任何的重复,所以j直接由6 变为1
第二个例子中,子串为:abcabcx
前缀ab
与 后边x 之前的串的后缀ab
相同
则j 由6变为了3
规律:j 的变化取决于当前字符之前的串的前后缀的相似程度
一个让人看着发迷的公式
我们把串各个位置的j 值的变化定义为一个数组next,next长度为子串的长度
然后我们有了这样的定义:
先写到这儿,稍后写next数组的推导 :)
- KMP算法next推导
- KMP算法推导
- KMP算法推导
- KMP算法next数组推导
- KMP 算法的数学推导
- 字符串匹配之KMP算法推导过程
- [学习笔记]KMP匹配算法及next推导过程
- KMP之nextval推导
- KMP算法中next数组和nextval数组值的推导
- KMP算法详解 【KMP】
- 【KMP】KMP算法模板
- KMP hihoCoder1015 KMP算法
- K_means算法推导
- EM算法推导
- EM算法推导过程
- BP神经网络算法推导
- meanshift算法推导
- BP算法推导过程
- 数据库操作(2)------------SQLite存储方式
- 深度学习笔记7 Working with Large Images 卷积特征提取
- 后缀式求值
- HDU 5119 Happy Matt Friends(DP)
- 搭建Git服务器
- KMP算法推导
- jstl
- 学习笔记
- cvCornerHarris角点检测
- Fleury算法求欧拉路径
- 关于计算机运行的理解
- 解决android.os.NetworkOnMainThreadException
- 创建简单的jquery插件
- STL之deque容器详解