KMP算法 → 计算next数组

这篇具有很好参考价值的文章主要介绍了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数组值的图例。

 

kmp算法求next,信息学竞赛,# 字符串,KMP算法
 

【研究生考试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: ababaaababaa

output: -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: ababaaababaa

output: 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



 文章来源地址https://www.toymoban.com/news/detail-588397.html

到了这里,关于KMP算法 → 计算next数组的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • KMP算法——(手把手算next数组)

    该算法核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数,从而达到快速匹配的目的。 KMP算法与BF算法(暴力算法)区别在于, 主串 的i不会回退,并且 模式串 的j不会每次都回到0位置。 第一个问题:为什么主串的i不需要回退? 看如下两个字符串: a b c d

    2023年04月18日
    浏览(38)
  • 【KMP】从原理上详解next数组和nextval数组

    本文将从原理上详细解释KMP算法中的 next 数组以及 nextval 数组,尽量让大家明白它们到底在记录什么,为什么要这样算。以及 现在普遍的KMP算法实现当中的next数组与前两者有何不同 。篇幅较长,但尽量讲清楚。 虽然数据结构中对next数组有定义,但并不易于理解,因此我个

    2024年02月06日
    浏览(45)
  • 【kmp算法】字符串匹配

    kmp算法解决的是字符串匹配的问题,具体来说假定我们要在主串s[ ] 中匹配模式串p[ ],找到匹配到的位置loc; 最自然的想法是暴力写法 (BF)枚举主串字符s[ i ] ,和模式串p[ j ]。一个一个匹配,如果匹配失败,i指针回退回起点,往前进一位,再次进行比较,知道匹配成功。

    2024年02月04日
    浏览(73)
  • 字符串匹配算法:KMP

    Knuth–Morris–Pratt(KMP)是由三位数学家克努斯、莫里斯、普拉特同时发现,所有人们用三个人的名字来称呼这种算法,KMP是一种改进的字符串匹配算法,它的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。它的时间复杂度是 O(m+n) 字

    2024年02月06日
    浏览(60)
  • 字符串匹配-KMP算法

    KMP算法,字符串匹配算法,给定一个主串S,和一个字串T,返回字串T与之S匹配的数组下标。 在学KMP算法之前,对于两个字符串,主串S,和字串T,我们根据暴力匹配,定义两个指针,i指向主串S的起始,j指向字串T的起始,依次比较,如果 主串i位置的值等于子串j位置的值,

    2024年02月14日
    浏览(54)
  • 字符串匹配算法(BF&&KMP)

    个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【数据结构初阶(C实现)】 在学习这个算法之前,我们先来看看什么时字符串匹配算法,简单来说 有一个主串和一个子串,查找子串在主串的位置,然后返回这个位置

    2023年04月17日
    浏览(39)
  • 数据结构--字符串的KMP算法

    朴素模式匹配算法: 一旦发现当前这个子串中某个字符不匹配,就只能转而匹配下一个子串(从头开始) 但我们可以知道: 不匹配的字符之前,一定是和模式串一致的 color{red}不匹配的字符之前,一定是和模式串一致的 不匹配的字符之前,一定是和模式串一致的 我们可以利用

    2024年02月12日
    浏览(61)
  • LeetCode:459. 重复的子字符串 —【2、KMP算法】

    🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀 算法专栏: 👉🏻123 题目描述 :给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。 来源:力扣(LeetCode) 难度: 简单 提示: 1 = s.length = 104 s 由小写英文字母组成 示例 1: 输入:

    2024年02月04日
    浏览(71)
  • 代码随想录 Leetcode459. 重复的子字符串(KMP算法)

            此解法读者需要了解什么是KMP算法以及KMP算法中next数组的具体含义才能理解         因为在KMP算法的next数组中,next[index]表示 i ndex之前的最大长度的相同前缀后缀值 ,那么要判断整个字符串中是否由重复字串构成,只需要以下两个条件:         1.next[n - 1] !=

    2024年01月19日
    浏览(74)
  • C#,字符串匹配(模式搜索)KMP算法的源代码与数据可视化

      D.E.Knuth   J.H.Morris KMP 算法(Knuth-Morris-Pratt 算法)是其中一个著名的、传统的字符串匹配算法,效率比较高。 KMP算法由 D.E.Knuth , J.H.Morris 和 V.R.Pratt 在 Brute-Force 算法的基础上提出的模式匹配的改进算法。因此人们称它为“克努特—莫里斯—普拉特算法”,简称KMP算法。K

    2024年01月25日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包