史上最透彻的KMP算法讲解
时间:2022-05-03
本文章向大家介绍史上最透彻的KMP算法讲解,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
作 者:柳行刚 编 辑:李文臣
1
字符串匹配是经典的KMP算法。下面以字符串"BBC ABCDAB ABCDABCDABDE"为例,查找是否包含串"ABCDABD"?
图一
2
首先如上图,字符串"BBC ABCDAB ABCDABCDABDE"的第一个字符与搜词"ABCDABD"的第一个字符,B与A不相等,所以后移动。
图二
3
上图中,D与空格不相等,但是它有前缀AB与后缀AB相当,KMP的思想就是利用最长的公共前缀与最长公共后缀相等,来加快每次不相等时移动的距离,来提高搜索效率。
4
要做到这一点,就是要生成一个next匹配数组,next匹配数据来决定匹配的最大长度。如图二。查next数组可知,最后一个匹配字符B对应的"部分匹配值"为2,因此后移动的位数:移动位数 = 已匹配的字符数 - 对应的部分匹配值。因为 6 - 2 等于4,所以将搜索词向后移动4位。
下面是next数组和匹配算法参照代码。
精彩内容
#include <cstring>
using namespace std;
const int N = 1000002;
int next[N];
char S[N], T[N];
int slen, tlen;
void getNext()
{
int j, k;
j = 0; k = -1; next[0] = -1;
while(j < tlen)
if(k == -1 || T[j] == T[k])
next[++j] = ++k;
else
k = next[k];
}
/*
返回模式串T在主串S中首次出现的位置
返回的位置是从0开始的。
*/
int KMP_Index()
{
int i = 0, j = 0;
getNext();
while(i < slen && j < tlen)
{
if(j == -1 || S[i] == T[j])
{
i++; j++;
}
else
j = next[j];
}
if(j == tlen)
return i - tlen;
else
return -1;
}
- node中子进程同步输出
- Java开源博客My-Blog之docker容器组件化修改
- 几个行列转换的实用小例子(r4笔记第2天)
- History API与浏览器历史堆栈管理
- node中创建服务进程
- 数据挖掘工程师:如何通过百度地图API抓取建筑物周边位置、房价信息
- crontab导致CPU异常的问题分析及处理(r3笔记第100天)
- 短信接口被恶意调用(二)肉搏战-阻止恶意请求
- 关于首屏时间采集自动化的解决方案
- javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites
- 一次数据库无法登陆的问题及排查 (r3笔记第99天)
- 用深度学习keras的cnn做图像识别分类,准确率达97%
- 短信发送接口被恶意访问的网络攻击事件(三)定位恶意IP的日志分析脚本
- job处理缓慢的性能问题排查与分析(r4笔记第18天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 威胁事件告警分析技巧及处置(一)
- docker数据卷备份恢复以及配置桥接网络
- ES对磁盘的要求都有哪些,大部分你可能不知道
- docker通过模板创建镜像以及容器、仓库和数据管理
- Form表单类组件与Map地图组件
- 转录组分析 | 使用Hisat2进行序列比对
- 最后一个页面:构建电影详情页面
- 安装docker以及通过容器创建镜像
- 转录组分析 | 使用trim-galore去除低质量的reads和adaptor
- 设计模式之工厂方法模式
- Ubuntu上安装TensorFlow(python2.7版)
- 转录组分析 | fastqc进行质控与结果解读
- playbook管理配置文件
- 使用playbook安装nginx
- 第五个页面:更多电影页面