KMP算法
来源:互联网 发布:mac双系统卸载 编辑:程序博客网 时间:2024/06/06 00:45
KMP算法是一种处理模式匹配问题的一种高效算法,其对于任何模式和目标序列,都可以在线性时间内完成匹配查找且不会发生退化。下面我们通过一个实例来讲解KMP算法。
主串:b a b c b a b c a b c a a b c a b c a b c a c a b c模式串:a b c a b c a c a b
最原始的方法,那就是我们从初始位置开始比对:
1)匹配:那我们主串模式串相对位置不变,比较位置都后移一位继续比对。
2)不匹配:那我们模式串相对于主串整体后移一位,从初始位置重新比对。
那对于KMP算法呢,我们可以这么理解我们例子中的模式串有重复的地方a b c ||a b c a c a b所以我们在比对的时候之前的前缀匹配过的话,那我们直接就可以跳过匹配过得部分,直接从下个位置开始,这也是我们KMP算法的思想所在。如下图:
那么我们的问题来了,如何确定每次匹配不成功要后移多少呢?
由此我们引入next数组,next[i]数组中存储的是位置1到位置i-1最长的公共子串的长度K,那么i-1减去next[i]就是当主串[i]与模式串[i]不匹配时,我们要移动的距离了。
此时分为两种情况:
1)模式串[i]和模式串[K+1]不相等:
此时i前面的公共子串长度为K,那么next[i]=K
2)模式串[i]和模式串[K+1]相等:
此时next[i]=next[K+1],原因如下图所示:
可以看到第二行不匹配后,我们直接从比较位置的后面开始比较,因为此处和模式前缀相同,此处不匹配那么前缀也一定不匹配,所以直接略过从后面重新比对。
下面我们给出计算例子中next[]的过程:
1. 首先我们把初始的next[1]=-1,
2. 接下来next[2],即a b的next值:
模式串[2]位置之前的公共子串长度为0,所以next[2]=0
3. 接下来next[3],即a b c的next值:
模式串[3]位置之前的公共子串长度为0,所以next[3]=0
4. 接下来next[4],即a b c a的next值:
模式串[4]位置之前的公共子串长度为0,但是模式串[4]与模式串[1]相等,所以next[4]=next[1]=-1
5. 接下来next[5],即a b c a b的next值:
模式串[5]位置之前的公共子串长度为1,但是模式串[5]与模式串[2]相等,所以next[5]=next[2]=0
6. 接下来next[6],即a b c a b c的next值:
模式串[6]位置之前的公共子串长度为2,但是模式串[6]与模式串[3]相等,所以next[6]=next[3]=0
7. 接下来next[7],即a b c a b c a的next值:
模式串[7]位置之前的公共子串长度为3,但是模式串[7]与模式串[4]相等,所以next[7]=next[4]=-1
8. 接下来next[8],即a b c a b c a c的next值:
模式串[8]位置之前的公共子串长度为4,所以next[8]=4
后面不再赘述。
注:要注意区分是模式串与主串不匹配,还是模式串内部的不匹配。
- KMP算法详解 【KMP】
- 【KMP】KMP算法模板
- KMP hihoCoder1015 KMP算法
- kmp算法
- KMP算法
- KMP算法
- KMP算法
- KMP算法
- KMP 算法
- kmp算法
- KMP算法
- kmp算法
- KMP算法
- KMP算法
- kmp算法
- kmp算法
- KMP算法
- KMP算法
- JSP代码段中直接访问值valuestack栈内容
- Java中static与this解析
- 树及树的遍历
- Spring声明式事务配置管理方法
- JS中匹配正整数
- KMP算法
- HTTP要点概述:九,HTTP获取部分内容的请求范围
- 【题解】 数学一本通 例1.2-1 指数取余
- 基于Qt的软件框架设计--续
- 数据压缩实验六:MPG音频编码
- ThinkPHP DB_FIELDS_CACHE 启用字段缓存跨库访问BUG
- TypeScript Symbols和迭代器
- MAVEN学习 (1):创建MAVEN项目并且理解基本的原理
- Java中文编程开发,让Java编写更加容易