KMP算法 → 计算next数组
【KMP算法简介】
KMP算法中的next数组仅取决于模式串本身,而与相匹配的主串无关。
KMP算法中的next数组,是KMP算法的核心。
KMP算法是由克努特(Knuth)、莫里斯(Morris)和普拉特(Pratt)共同设计实现的,因此简称KMP算法。此算法可以在O(n+m)的时间数量级上完成串的模式匹配操作。其相对于BF算法的改进在于:每当失配时,无须回溯主串的指针,而是利用已经得到的“部分匹配”的结果将模式串向右“滑动”尽可能远的一段距离后,继续进行比较。这个滑动的距离就是由next数组确定的。
KMP算法本身并不复杂,主要分为两步:求next[ ]数组、匹配字符串。但绝大部分的文章把它讲混乱了,以致造成很多混淆。
【求next数组的算法】
求next数组 在KMP算法的众多实现中,有许多种定义next数组的方式。所以在使用和查看别人代码时,要特别注意KMP算法的next数组的定义,以免发生混淆。如:
• 严蔚敏《数据结构》将模式串下标从1开始计数,故定义next[1]=0,next[2]=1;
• 李春葆《数据结构》将模式串下标从0开始计数,故定义next[0]=-1,next[1]=0。
情况一: 模式串下标从1开始时求next数组的算法
若在KMP算法设计中,将模式串下标从1开始计数,则定义next[1]=0,next[2]=1。那么求next数组的算法步骤为: (1)若第j-1位的字符与第x位的字符相等,则next[j]=x+1; (2)若直到第1位依然没有字符与第j-1位的字符相等,则next[j]=1。
显然,若按严蔚敏《数据结构》中模式串的定义方式(即定义next[1]=0,next[2]=1),可得出模式串ababaaab的next数组如下:
-------------------------------------------------------
j 1 2 3 4 5 6 7 8
-------------------------------------------------------
a b a b a a a b
-------------------------------------------------------
next[j] 0 1 1 2 3 4 2 2
-------------------------------------------------------
情况二:模式串下标从0开始时求next数组的算法
若在KMP算法设计中,将模式串下标从0开始计数,则定义next[0]=-1,next[1]=0。那么求next数组的算法步骤为: (1)若第j-1位的字符与第x位的字符相等,则next[j]=x+1; (2)若直到第0位依然没有字符与第j-1位的字符相等,则next[j]=0。
显然,若按李春葆《数据结构》中模式串的定义方式(即定义next[0]=-1,next[1]=0),可得出模式串abcabaa的next数组如下:
-------------------------------------------------
j 0 1 2 3 4 5 6
-------------------------------------------------
a b c a b a a
-------------------------------------------------
next[j] -1 0 0 0 1 2 1
-------------------------------------------------
但这两种定义方式,不影响它们有一致的计算方法,即“若第j-1位的字符与第x位的字符相等,则next[j]=x+1”(特别注意:在此判别过程中,所谓的第x位是由已经计算出的next[j-1] → next[0]间的若干值跳转抵达)。
个人喜欢采用李春葆《数据结构》中模式串的定义方式(即定义next[0]=-1,next[1]=0),并据此给出了如下图所示的求j=4时模式串元素b的next数组值的图例。
【研究生考试2015年第8题】
已知字符串s为“abaabaabacacaabaabcc”,模式串t为“abaabc”。采用KMP算法进行匹配,第一次出现“失配”( s[i]!=t[j] )时,i=j=5,则下次开始匹配时,i和j的值分别是( C )。
A. i=1,j=0 B. i=5,j=0 C. i=5,j=2 D. i=6,j=2
【输出李春葆定义法next数组值的算法代码】
#include<iostream>
using namespace std;const int maxn=100;
int ne[maxn];void getNext(string s) {int len=s.length(); //First of all, you must calculate the length of the string.int i=0, j=-1;ne[0]=-1;while(i<len) {if(j==-1 || s[i]==s[j]) {ne[++i]=++j;} else j=ne[j];}
}int main() {string T;getline(cin,T);getNext(T);for(int i=0; i<T.length(); i++) {cout<<ne[i]<<" ";}return 0;
}/*
input: ababaaababaaoutput: -1 0 0 1 2 3 1 1 2 3 4 5
*/
【输出严蔚敏定义法next数组值的算法代码】
#include<iostream>
using namespace std;const int maxn=100;
int ne[maxn];void getNext(string s) {int len=s.length(); //First of all, you must calculate the length of the string.int i=0, j=-1;ne[0]=-1;while(i<len) {if(j==-1 || s[i]==s[j]) {ne[++i]=++j;} else j=ne[j];}
}int main() {string T;getline(cin,T);getNext(T);for(int i=0; i<T.length(); i++) {cout<<ne[i]+1<<" ";}return 0;
}/*
input: ababaaababaaoutput: 0 1 1 2 3 4 2 2 3 4 5 6
*/
【参考文献】
https://blog.csdn.net/dark_cy/article/details/88698736
https://www.zhihu.com/question/21923021
KMP算法 → 计算next数组相关推荐
- KMP算法 → 计算nextval数组
[算法解析] ● 众所周知,KMP算法中模式串T的next数组,是KMP算法的核心. next数组的核心作用是"当模式串T的第j位与主串S的第pos位失配时(即 T[j]≠S[pos] 时) ...
- KMP算法计算next数组和nextval数组(通俗易懂)
KMP算法(举例说明) 例:给出一个字符串序列:ababaaababaa.利用KMP算法分别求出next数组和nextval数组 分析: 数组索引:0-n 逻辑索引:1-n next数组: 1.nex ...
- KMP算法之next数组详解
KMP算法之next数组详解 KMP算法实现原理 KMP算法是一种非常高效的字符串匹配算法,下面我们来讲解一下KMP算如何高效的实现字符串匹配.我们假设如下主串和模式串: int i;//i表示主串的 ...
- KMP算法的next数组通俗解释
我们在一个母字符串中查找一个子字符串有很多方法.KMP是一种最常见的改进算法,它可以在匹配过程中失配的情况下,有效地多往后面跳几个字符,加快匹配速度. 当然我们可以看到这个算法针对的是子串有对称属性, ...
- KMP算法之NEXT数组代码原理分析 - 数据结构和算法38
KMP算法之NEXT数组代码原理分析 让编程改变世界 Change the world by program KMP算法之NEXT数组代码原理分析 NEXT数组:当模式匹配串T失配的时候,NEXT数组 ...
- 数据结构与算法之KMP算法中Next数组代码原理分析
2019独角兽企业重金招聘Python工程师标准>>> 一.KMP算法之Next数组代码原理分析 1.Next数组定义 当模式匹配串T失配的时候,Next数组对应的元素指 ...
- KMP算法及next数组(最大公共前后缀)求解
KMP算法及next数组(最大公共前后缀)求解 2020.12.14理解: 1. KMP算法 网上关于KMP算法讲解较为简单易懂,因此在此只作简述: 在字符串s中匹配字符串t: S: ABE-AB-A ...
- 看了这个你基本就会算kmp算法的next数组了
看了这个你基本就会算kmp算法的next数组了 kmp算法的next数组求解在计算机专业考研中,以及在大学的数据结构考试中等场合可能会遇到,而遇到后,可能很多同学绕绕脑袋,抓抓头发,却发现还是做不来. ...
- KMP算法中next数组的理解与算法的实现(java语言)
KMP 算法我们有写好的函数帮我们计算 Next 数组的值和 Nextval 数组的值,但是如果是考试,那就只能自己来手算这两个数组了,这里分享一下我的计算方法吧. 计算前缀 Next[i] 的值: ...
最新文章
- 下载SpringJar包
- 邓俊辉数据结构学习-3-栈
- Xml,XPath,XSLTxue 学习方法
- Windows下使用MinGw和gcc构建第一个C程序、g++构建第一个C++程序
- Ardino基础教程 22_PS2摇杆
- SQL Server 索引重建或索引重組
- ComponentBase.createMetaData and manifest.json oRoute
- 线程打印_面试题:用程序实现两个线程交替打印 0~100 的奇偶数
- [Redis6]常用数据类型_Zset有序集合
- RegistryHelper-注册表辅助类
- 数组 , List互转
- Java 窗口设置图标及背景图片
- JAVA调用百度OCR实现身份证识别
- 抖音超火的数字炸弹 c++ 实现
- Vue导出页面为PDF格式,解决PDF中图片不显示(跨域)
- python在mac模拟鼠标点击_python模拟鼠标点击和键盘输入的操作
- 你不能错过的超赞色彩组合
- LVS之ipvsadm命令
- 自定义实现IOC与DI
- M1 pod install CocoaPod 报错解决办法
热门文章
- web移动端实现打电话和保存到电话簿功能
- 从番茄花园想到的。。。。
- XQuery基本介绍
- 学术-物理-维空间:四维空间(标准欧几里得空间)
- 购买计算机的英语作业,《计算机专业英语》作业
- postgresql.util.PSQLException: 不良的类型值 int : 2020-11-19 02:47:05.013
- C语言中数的二进制、八进制、十进制以及十六进制表示及输出
- [置顶]▁▂▃ Himi 著作《Android游戏编程之从零开始》★书籍源码免费下载★ ▃▂▁...
- 画流程图软件哪个好?快来看看这些软件
- mysql limit where_mysql select ,where,limit查询