KMP算法next数组详解
==> 学习汇总(持续更新)
==> 从零搭建后端基础设施系列(一)-- 背景介绍
KMP算法的核心就是利用已匹配的信息来指导模式串的匹配。这里的已匹配信息叫做部分匹配表,也叫做next数组。其存储的是字符串的前缀后缀重合部分的字符数。以此来控制模式串的移动位数。
next数组生成的步骤:
假设模式串是“ABABABB”
**前缀:**除最后一个字符外,例如,A、AB、ABA、ABAB、ABABA、ABABAB
**后缀:**除第一个字符外,例如,B、BB、ABB、BABB、ABABB、BABABB
1.字符串“A”无前缀后缀,所以 next[1]=0 (至于为什么next数组从1开始,代码会讲到,暂且不要纠结)
2.字符串“AB”前缀“A”和后缀“B”不相等,所以 next[2]=0
3.字符串“ABA”前缀“A”和后缀“B”相等,所以 next[3]=1
4.字符串“ABAB”前缀“AB”和后缀“AB”相等,所以 next[4]=2
5.字符串“ABABA”前缀“ABA”和后缀“ABA”相等,所以 next[5]=3
6.字符串“ABABAB”前缀“ABAB”和后缀“ABAB”相等,所以 next[6]=4
因为最后一个并无指导意义,所以不需理它。
接下来看详细的代码:
/*
* function 生成部分匹配表,next数组
* param subStr 模式串,子串
* param next next数组,部分匹配信息表
* param len next数组的长度,一般就是模式串的长度
* return 无
*/
void GetNext(const char* subStr, int* next, int len)
{memset(next, 0, len);int prefix = -1; //前缀int suffix = 0; //后缀next[0] = -1; //第一个元素只是用来控制prefix和suffix后移的while (suffix < len - 1)//当比较到最后一个字符的时候退出循环{/*当prefix == -1的时候表示要从prefix=0,suffix=1开始比较若prefix != -1,表示前缀和后缀已经有重合的了,接着往后移比较例如:subStr="ABABABB"1.prefix=-1,往后移,prefix=0,suffix=1,next[1] = 0,表示字符串‘A’前缀后缀无重合2.prefix=0,比较subStr[0]和subStr[1]('A'和'B'),不相等,把prefix重新置为next[prefix](next[0]==-1)3.prefix=-1,往后移,prefix=0,suffix=2,next[2] = 0,表示字符串‘AB’前缀后缀无重合4.prefix=0,比较subStr[0]和subStr[2]('A'和'A'),相等,继续往后移,prefix=1,suffix=3,next[3]=1表示字符串"ABA"有一个字符前缀后缀相等('A'和'A')5.prefix=1,比较subStr[1]和subStr[3]('B'和'B'),相等,继续往后移,prefix=2,suffix=4,next[4]=2表示字符串"ABAB"有两个字符前缀后缀相等('AB'和'AB')6.prefix=2,比较subStr[2]和subStr[4]('A'和'A'),相等,继续往后移,prefix=3,suffix=5,next[5]=3表示字符串"ABABA"有三个字符前缀后缀相等('ABA'和'ABA')7.prefix=3,比较subStr[3]和subStr[5]('B'和'B'),相等,继续往后移,prefix=4,suffix=6,next[6]=4表示字符串"ABABAB"有四个字符前缀后缀相等('ABAB'和'ABAB')8.当suffix=6最后一个的时候,就不需要比较了,因为KMP算法中最后一个并无指导匹配的作用,因为一旦前6个匹配成功,最后一个就算不成功,用到的也是前一个的部分匹配信息,若是成功那就直接返回了,所以求next数组的时候,最后一个的信息省略 */if (prefix == -1 || subStr[prefix] == subStr[suffix]){++prefix, ++suffix; next[suffix] = prefix;printf("%d ", next[suffix]); //测试用,可删除}elseprefix = next[prefix];}printf("\n"); //测试用,可删除
}
测试结果如图:
顺序表的动态增长(C++、JAVA)
栈、递归、循环的关系(C++、JAVA)
栈应用之中缀转后缀表达式计算(C++、JAVA)
栈应用之中缀转后缀表达式(C语言版)
约瑟夫问题详解+源码
线性表之循环队列
线性表之链队列
线性表之顺序队列
线性表之链栈
线性表之顺序栈
线性表之双向链表
线性表之循环链表
线性表之单链表
线性表之顺序表
KMP算法next数组详解相关推荐
- 字符串:3.KMP算法(快速模式匹配算法)详解
BF算法的改进--KMP算法(快速模式匹配算法). 串的普通模式匹配算法,大体思路是:模式串从主串的第一个字符开始匹配,每匹配失败,主串中记录匹配进度的指针 i 都要进行 i-j+1 的回退操作(这个 ...
- 字符串匹配代码C语言,KMP算法(快速模式匹配算法)详解以及C语言实现
通过上一节的介绍,学习了普通模式匹配算法,大体思路是:模式串从主串的第一个字符开始匹配,每匹配失败,主串中记录匹配进度的指针 i 都要进行 i-j+1 的回退操作(这个过程称为"指针回溯&q ...
- c语言实现sha1算法注解,【密码学】SHA1算法实现及详解
1 SHA1算法简介 安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digit ...
- KMP算法之next数组详解
KMP算法之next数组详解 KMP算法实现原理 KMP算法是一种非常高效的字符串匹配算法,下面我们来讲解一下KMP算如何高效的实现字符串匹配.我们假设如下主串和模式串: int i;//i表示主串的 ...
- JavaScript数据结构与算法——数组详解(下)
1.二维与多维数组 JavaScript只支持一维数组,但是通过在数组里保存数组元素的方式,可以轻松创建多维数组. 1.1 创建二维数组 二维数组类似一种由行和列构成的数组表格,在JavaScript ...
- JavaScript数组结构与算法——数组详解(中)
迭代器方法 在上篇中,我们探讨了很多数组方法,接下来总结一下最后一组方法--迭代器方法.这些方法对数组的每个元素应用一个函数,可以返回一个值.一组值.或者一个新数组. 1.不生成新数组的迭代器方法 以 ...
- 【算法知识】详解堆排序算法
点击蓝色字关注我们! 什么是堆 「堆」首先是一个完全二叉树,「堆」分为「大顶堆」和「小顶堆」: 「大顶堆」 : 每个节点的值大于或等于其左右孩子节点的值,称为大顶堆. 「小顶堆」同理就是每个节点的值小 ...
- 【算法知识】详解基数排序算法
已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 [算法知识]详解快速排序算法 [算法知识]详解归并排序算法 基本思想 基数排序的思想是将整数按位数切 ...
- 【算法知识】详解归并排序算法
已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 [算法知识]详解快速排序算法 基本思想 归并排序的基本思想是: 先将序列一次次分成子序列,直到子序列 ...
最新文章
- 计算机基础及应用教案,计算机应用基础教案:数制的概念及转换(中职教育)
- kafka-manager 的编译和使用(附安装包)
- 华为鸿蒙10月17日,华为宣布10月17日重磅新机:鸿蒙系统+全球首发屏下摄像头...
- objective-c 逐帧动画
- oracle jinitiator 1.1.8.2,oracle jinitiator 1.1.8.2-Oracle Jinitiator1.1.8.27 3264位最新版下载_东坡手机下载...
- MySQL无法启动 服务没有报告任何错误
- python中again函数怎么用_Python中的偏函数怎么用?
- UVA10341 Solve It【二分】
- Linux常用的网络服务基础命令
- fckeditor for java_FCKeditor最新版本2.4.1 for java 教程
- 更改图书信息c语言编码,图书管理系统C语言实现源代码.pdf
- 计算机辅助翻译 火云译客,中文在线翻译韩语
- 怎么自己制作一个U盘
- newifi刷老毛子笔记
- 数据库 - 交集、并集和补集
- 几何图形经常使用的公式解读(三)
- NutUI 京东小程序发布了!
- 赏析角度有哪些_几种分析的角度
- 开发辅助:从Eclipse转到Android Studio/Intellij Idea需要做的设置
- cinder云硬盘type创建