KMP算法学习记录----《大话数据结构》部分匹配表学习部分

如需转载,请保留本文链接.

首先先将《大话数据结构》关于KMP算法的讲解部分贴上,本文不提供下载链接,也不会将电子书作为资料留百度云,需要电子书的各位,请自行寻找电子版.

关于上述的KMP算法种的next数组的推导部分,一直不是很明白,本贴是关于上述部分的学习推导记录.

以书中字符串为例:

1|2|3|4|5|6|7|8|9|

a|b|a|b|a|a|a|b|a|

0|1|1|2|3|4|2|2|3|

string T = "ababaaaba";

int i = 1;j = 0;//这里最让我费解的其实是序列号,只要明白本书中的KMP算法,序列号都是从1开始计算的,就会好理解了很多.

next[1] = 0;

while(i<T[0])//或者写成T.Length

{

  if(j == 0 || T[i] == T[j])//T[i]代表后缀的第一个字符,T[j]代表前缀中的某一个字母,j记录了当前相等的字符个数

  {

    ++i;

    ++j;

    next[i] = j;

  }

  else

  {

    j = next[j];//所有部分匹配值均取自j的数据,且,满足if条件时,计算出的是下一个i值对应的部分匹配数据,这就意味着next[j]的值永远小于j,

        //但是关于j的回溯个数,目前并没有很好的理解,初步认为只是利用next[j]值小于j值进行回溯,跟当前的前后缀相等字符数无关

  }

}

以下为while循环详细分解,记录学习过程.

第一步:由于前缀与后缀均来自于子串,部分匹配表则是子串的自我匹配程度反应,那么当子串长度为1时,不存在前缀与后缀,由此可得:next[1] = 0;

第二步:i = 1;j = 0;满足if判断条件,i,j++;next[2] = 1;此时i = 2;j = 1;

第三步:i = 2;j = 1;

  T[i = 2] = "b";

  T[j = 1] = "a";-------------"ab"[前缀与后缀相等个数的下一字符索引值,后缀字符]

  else

  {

    j = next[j] = next[1] = 0;

  }

  j = 0;

  i,j++;

  next[3] = 1;//此时i = 3;j = 1;

第四步:i = 3;j = 1;

  T[i = 3] = "a";

  T[j =1] = "a";----------"aba"[前缀与后缀相等的个数的下一字符索引值,b,后缀字母]

  i,j++;

  next[4] = 2;//此时i = 4;j = 2;

第五步:i = 4;j = 2;

  T[i = 4] = "b";

  T[j = 2] = "b";----------"abab"[a,前缀与后缀相等的个数的下一字符索引值,a,后缀字母]

  i,j++;

  next[5] = 3;//此时i = 5;j = 3;

第六步:i  = 5;j = 3;

  T[i = 5] = "a";

  T[j = 3] = "a";-----------"ababa"[a,b,前缀与后缀相等的个数的下一字符索引值,b,后缀字母]

  i,j++;

  next[6] = 4;//此时i = 6;j = 4;

第七步:i = 6;j = 4;

  T[i = 6] = "a";

  T[j = 4] = "b";-------"ababaa"[a,b,a,前缀与后缀相等的个数的下一字符索引值,a,后缀字母]

  else

  {

    j = next[4] = 2;//j值进行回溯

  }

  j = 2;

  T[j = 2] = "b";-------------"ababaa"[a,?,a,b,a,后缀字母]不确定含义,暂用问号代替

  elst

  {

    j = next[2] = 1;//j值进行回溯

  }

  j = 1;

  T[j = 1] = "a";---------------"ababaa"[?,b,a,b,a,后缀字母]

  与T[i = 6]进行对比

  i,j++;

  next[7] = 2;//此时i = 7;j = 2;

第八步:i = 7;j = 2;

  T[i = 7] = "a";

  T[j = 2] = "b";---------"ababaaa"[a,前缀与后缀相等的个数的下一字符索引值,a,b,a,a,后缀字母]

  else

  {

    j = next[j] = next[2] = 1;

  }

  j = 1;

  T[j = 1] = "a";-----------------"ababaaa"[前缀与后缀相等的个数的下一字符索引值,b,a,b,a,a,后缀字母]

  i,j++;

  next[8] = 2;//此时i= 8;j = 2;

第九步:i = 8;j = 2;

  T[i = 8] = "b";

  T[j = 2] = "b";---------------"ababaaab"[a,前缀与后缀相等的个数的下一字符索引值,a,b,a,a,a,后缀字母]

  i,j++;

  next[9] = 3;//此时i = 9;j = 3;

此时关于字符串"ababaaaba"的部分匹配表完全推导完毕,答案与书上结果一直,但是关于i = 6时,j回溯如何做解释,还需要再看,我在另外的字符串"aaaaabbbc"中,j的回溯每次回溯一位,得到的部分匹配表为:012345511,欢迎留言指正,结束.

原文地址:https://www.cnblogs.com/yikecaidechengzhangshi/p/8576061.html

时间: 2024-10-30 03:56:29

KMP算法学习记录----《大话数据结构》部分匹配表学习部分的相关文章

学习记录:数据结构与算法分析c++版

数据结构与算法分析c++版 学习记录 一.绪论 1.数据结构的必要性 计算机程序被设计出来的目的不仅仅是为了计算,同时其也要完成数据的提取和检索任务,并尽可能地高效快速.在这个意义下,数据结构和算法分析作为程序的核心,就显得尤为重要.如何利用数据结构和算法,设计出简单易懂,并且高效地利用计算机资源的程序是这门课的核心议题. Def    一个算法被称为有效的(effective),如果其能在计算机的资源限制下解决相应问题:这些限制通常包括计算机储存量限制,以及算法运行的时间限制.    算法的消

【Java】 大话数据结构(2) 线性表之单链表

本文根据<大话数据结构>一书,实现了Java版的单链表. 书中的线性表抽象数据类型定义如下(第45页): 实现程序: package LinkList; /** * 说明: * 1.<大话数据结构>中没有线性表的长度,但提到可以存储于头节点的数据域中. * 本程序的线性表长度存放于count变量中,线性表长度可以使程序比较方便. * 2.程序中,第i个位置代表第i个结点,头结点属于第0个结点 * 3.因为链表为泛型,整表创建采用整型(随机整数做元素),所以有出现一些类型转换 * 4

【Java】 大话数据结构(6) 线性表之栈

本文根据<大话数据结构>一书,实现了Java版的栈的顺序存储结构.两栈共享空间.栈的链式存储机构. 栈:限定仅在表尾进行插入和删除操作的线性表. 栈的插入(进栈)和删除(出栈)操作如下图所示.   1.栈的顺序存储结构 用数组存放数据,top变量来指示栈顶元素在数组中的位置(栈顶指针).一个长度为5的栈的示意图如下: 实现程序: /** * 栈的顺序储存结构 * * 问题:构造器中,泛型数组创建是否有更好的方法? * @author Yongh * */ public class SqStac

(源代码见大话数据结构)线性表—链式存储结构-&gt;单链表的删除ListDelet(*L,i,*e)

Status ListDelet(LinkList *L,int i,ElemType *e) { int j=1; LinkList p,s; p=*L; while(p&&j<i) { p=p->next; j++; } if(!p||j>i) return ERROR; s=p->next; *e=s->data; p->next=s->next; free(s); return OK; } 个人理解:建立一个新结点可以作为(i-1)个结点的

[读书笔记]-大话数据结构-3-线性表(三)-静态链表、循环链表和双向链表

静态链表 对于没有指针的编程语言,可以用数组替代指针,来描述链表.让数组的每个元素由data和cur两部分组成,其中cur相当于链表的next指针,这种用数组描述的链表叫做静态链表,这种描述方法叫做游标实现法.我们对数组的第一个和最后一个元素做特殊处理,不存数据.让数组的第一个元素cur存放第一个备用元素(未被占用的元素)下标,而数组的最后一个元素cur存放第一个有值的元素下标,相当于头结点作用.空的静态链表如下图 当存放入一些数据时("甲""乙""丁&q

HttpClient学习记录-系列2(源码学习)

如何阅读第三方工具源码? 存在多个入口,而且整个类图存在很多孤岛,自上而下的分析策略貌似不行,还是从use case入手,针对单个面分析.难点是如何做范围界定?不至于陷入黑洞 HttpGet   ---> HttpRequestBase --> AbstractHttpMessage --> HttpMessage 原文地址:https://www.cnblogs.com/caiyao/p/9152752.html

Python入门基础学习记录(二)汇率案例学习记录

一.汇总整理 1.操作 ①新建python文件 工程右键--new--python file 2.注意问题与知识点 >变量定义:直接写变量名即可,例如定义一个字符串并赋值123: rmb_str = ‘123’.特别需要注意的,python对格式的要求,等号左右要有空格 >代码缩进:python中没有类似C#.java等以花括号或其它开始结束定界符来区分代码块,缩进是标识语句块的唯一方法,一个语句块中的所语句必须使用相同的缩进,表示一个连续的逻辑行序列.注意:原文件的第一行不需要缩进,不可以用

数据结构与算法JavaScript (五) 串(经典KMP算法)

数据结构与算法JavaScript (五) 串(经典KMP算法) KMP算法和BM算法 KMP是前缀匹配和BM后缀匹配的经典算法,看得出来前缀匹配和后缀匹配的区别就仅仅在于比较的顺序不同 前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从 左到右 后缀匹配是指:模式串和母串的的比较从右到左,模式串的移动从左到右. 通过上一章显而易见BF算法也是属于前缀的算法,不过就非常霸蛮的逐个匹配的效率自然不用提了O(mn),网上蛋疼的KMP是讲解很多,基本都是走的高大上路线看的你也是一头雾水,我试

七分钟理解什么是 KMP 算法

本文是介绍 什么是 BF算法.KMP算法.BM算法 三部曲之一. KMP算法 内部涉及到的数学原理与知识太多,本文只会对 KMP算法 的运行过程. 部分匹配表 .next数组 进行介绍,如果理解了这三点再去阅读其它有关 KMP算法 的文章肯定能有个清晰的认识. 以下的文字描述请结合视频动画来阅读~ 视频地址:https://www.bilibili.com/video/av60334201/ 定义 Knuth-Morris-Pratt 字符串查找算法,简称为 KMP算法,常用于在一个文本串 S