`
saybody
  • 浏览: 869439 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

记录KMP算法,记录其经典之处。。。

阅读更多
离开学校已经多年了,早已经不再抚弄那些陈旧的书籍。
周末,深圳的天气阴沉,老天这段时间总是很乐意显摆,动不动就给深圳人民来次几十年一遇的暴雨,似乎要把一年的雨水全部在这些天下完似的。
所以呆在家里面看电视,上网,实在也无聊。随手翻开大学时候的(数据结构,还留着啊,当初刚出来的时候总没有底气,总希望能够随时充电用)。看到了字符串的模式匹配一章。突然发现KMP算法是如此的经典。故记之。。。
在提KMP的经典之前,首先要提基本的模式匹配算法:
所谓模式匹配,简单点说就是对两字符串进行匹配,找出一个字符串在另一个字符串中的位置。
基本的模式匹配是这样的:
假设有字符串
S=S1S2......SN(由于为了算法效率的需要,所以一般都把S[0]保存S的长度)
P=P1P2......PM(同上)
其中(M<N),要求返回P在S中出现的位置。
所以算法要点如下:
假设从S中i点开始扫描(也就是从S[i]开始,此时用一个变量k=i),顺序比较S[i]和P[1],S[i+1]和P[2]。这样,当P进行到第j个字符也就是P[j]的时候,发现S[i+j-1]和P[j]不匹配,那么需要把S的指针i回朔到S起始的下一个字符也就是k+1继续比较。

如图:

以上就是模式匹配的基本算法,这种算法对于大多数的匹配来说基本是O(N+M)的时间复杂度。
但是对于如下的字符串:
S=0000000000000000000000000000001
P=000001
这种字符串来说,每次匹配失败都是在P到最后一个字符也就是j=M的时候,此时S的指针又必须回朔,导致大量的匹配。此时的时间复杂度是O(N*M)。
所以基本算法的时间复杂度是O(N*M)。当然了,对于大多数的匹配是不会有这么高的时间复杂度的,所以这种算法现在也在广泛使用,因为简单。
为了解决上述的问题,KMP算法被发现。
KMP算法的思想如下。匹配过程中,出现不匹配时,S的指针不进行回朔(原地不动),将P尽可能地向后移动一定的距离,再进行匹配。

如图:

从上图中我们看到,当S移动到i,P到j的时候失配。这时候i不回朔,而只是将P向前移动尽可能的距离,继续比较。
假设,P向右移动一定距离后,第k个字符P[k]和S[i]进行比较。
此时如上图,当P[j]和S[i]失配后,i不动,将P前移到K,让P[k]和S[i]继续匹配。现在的关键是K的值是多少?
通过上图,我们发现,因为黄色部分表示已经匹配了的结果(因为是到了S[i]和P[j]的时候才失配,所以Si-j+1Si-j+2…Si-1 = P1P2…Pj-1,见黄色的部分)。所以有:
1、Si-k+1Si-k+2…Si-1 = Pj-k+1Pj-k+2…Pj-1
所以当P前移到K时,有:
2、Si-k+1Si-k+2…Si-1 = P1P2…Pk-1
通过1,2有
Pj-k+1Pj-k+2…Pj-1 = P1P2…Pk-1
呵呵,此时我们的任务就是求这个k值了。。。
理解了这一点之后,终于能够发现此算法的经典了。
分享到:
评论
1 楼 saieuler 2012-09-18  
每次都是学会了,过段时间又忘了

相关推荐

    KMP算法,求子字符串位置

    数据结构书上的KMP算法,书上的算法看的不太明白,自己写了一个,有点罗嗦。 也是自己写的,容易看懂

    KMP算法,全称Knuth-Morris-Pratt算法,是一种线性时间复杂度的字符串匹配算法.pdf

    KMP算法的核心思想是利用已经匹配过的信息,当发生不匹配时,知道一些字符肯定不会出现在模式串的某个位置,从而利用这些信息跳过一些不必要的比较。具体来说,KMP算法通过维护一个“部分匹配表”(也称为“失败函数...

    c# 实现KMP算法的示例代码

    KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配...

    KMP(Knuth-Morris-Pratt)算法简介及C语言实现.docx

    KMP算法,全称Knuth-Morris-Pratt算法,是一种用于在一个主文本字符串(text)中查找一个模式字符串(pattern)的子串的高效算法。KMP算法的核心思想是利用模式字符串的特点,在匹配过程中尽可能地减少重复的字符...

    字符串的模式匹配详解--BF算法与KMP算法

    记录一下串里面的模式匹配,模式匹配,顾名思义就是给定一个被匹配的字符串,然后用一个字符串模式(模型)去匹配上面说的字符串,看后者是否在前者里面出现。常用的有2种算法可以实现,下面我们来具体探讨下

    深入串的模式匹配算法(普通算法和KMP算法)的详解

    算法的时间复杂度为O(m*n),算法如下: 代码如下://朴素的串的模式匹配算法,S为主串,T为模式串,即找S中有没有与T相同的字串int Index(char *S, char *T, int pos)//pos记录从哪一位开始匹配可以直接用0代替{ ...

    基于C语言实现kmp算法(源码)

    1. **构建模式串的部分匹配表... - 若相等,则部分匹配值加1,并将当前位置的部分匹配值记录在部分匹配表中。 - 若不相等,根据部分匹配表的值进行位置调整,直到找到一个匹配的前缀和后缀。 4. **代码实现**:

    一种基于KMP的高效字符串匹配算法 (2010年)

    串匹配(String Matching)问题是计算机科学中的一个基本... 该算法以KMP为基础, 引入好字符表以记录模式串最末字符在模式串中出现的位置信息, 从而获得模式串的最大移动距离. 实验结果表明, IKMP算法有效降低匹配次数.

    c语言数据结构算法演示(Windows版)

    本课件是一个动态演示数据结构算法执行过程的辅助教学软件, 它可适应读者对算法的输入数据和过程执行的控制方式的不同需求, 在计算机的屏幕上显示算法执行过程中数据的逻辑结构或存储结构的变化状况或递归算法执行...

    青蛙过河leetcode-LeetCode:python3实现经典算法题

    1、KMP算法---字符串匹配 利用字符串最长相同前缀后缀减少没必要的比较从而加快匹配 2、汉诺塔移动---由大化小 3、code 1:两数之和 4、code 15:三数之和 5、code 208:前缀树 6、code 212:单词搜索 7、code 845:...

    lrucacheleetcode-leetcode:leetcode算法学习记录golang版

    经典题目解析&golang版代码 简单难度 中等难度 困难难度 算法专项 KMP 算法 动态规划: 887. 鸡蛋掉落 5. 最长回文子串 494. 目标和 322. 零钱兑换 279. 完全平方数 198. 打家劫舍 152. 乘积最大子序列 139. 单词拆分...

    leetcode算法题主函数如何写-Learn-Algorithms:学习算法

    KMP算法 BM算法 正则表达式 数据压缩 二叉树 二叉树 二叉查找树 伸展树(splay tree 分裂树) 平衡二叉树AVL 红黑树 B树,B+,B* R树 Trie树(前缀树) 后缀树 最优二叉树(赫夫曼树) 二叉堆 (大根堆,小根堆) 二项树 二...

    java编写的记事本

    多功能记事本,除了基本功能外,还有像word中的历史记录,撤销,字符统计,统计选择字符数,替换等功能,纯java编写,还有kmp算法

    leetcode和oj-Algorithms:算法

    KMP算法 BM算法 正则表达式 数据压缩 二叉树 二叉树 二叉查找树 伸展树(splay tree 分裂树) 平衡二叉树AVL 红黑树 B树,B+,B* R树 Trie树(前缀树) 后缀树 最优二叉树(赫夫曼树) 二叉堆 (大根堆,小根堆) 二项树 二...

    leetcode中国-algorithm:算法

    KMP算法 BM算法 正则表达式 数据压缩 树 二叉树 二叉查找树 伸展树(splay tree 分裂树) 平衡二叉树AVL 红黑树 B树,B+,B* R树 Trie树(前缀树) 后缀树 最优二叉树(赫夫曼树) 二叉堆 (大根堆,小根堆) 二项树 二项堆 ...

    leetcode和oj-Learn-Algorithms:学习算法

    KMP算法 BM算法 正则表达式 数据压缩 二叉树 二叉树 二叉查找树 伸展树(splay tree 分裂树) 平衡二叉树AVL 红黑树 B树,B+,B* R树 Trie树(前缀树) 后缀树 最优二叉树(赫夫曼树) 二叉堆 (大根堆,小根堆) 二项树 二...

    leetcode和oj-algorithms:业余时间刷算法

    KMP算法 BM算法 正则表达式 数据压缩 二叉树 二叉树 二叉查找树 伸展树(splay tree 分裂树) 平衡二叉树AVL 红黑树 B树,B+,B* R树 Trie树(前缀树) 后缀树 最优二叉树(赫夫曼树) 二叉堆 (大根堆,小根堆) 二项树 二...

    leetcode和oj-Data-Structures-and-Algorithms:数据结构与算法

    KMP算法 BM算法 正则表达式 数据压缩 图的算法 图的存储结构和基本操作(建立,遍历,删除节点,添加节点) 最小生成树 拓扑排序 关键路径 最短路径: Floyd,Dijkstra,bellman-ford,spfa 排序算法 交换排序算法 冒泡...

Global site tag (gtag.js) - Google Analytics