学习记录---KMP算法-部分匹配表理解

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

看了 阮一峰 大神的字符串匹配的KMP算法后,关于部分匹配的部分并不是很理解,特意去看了阮大神文章中的英文链接,这里写下自己的理解,用作学习记录.

阮大神文章链接:https://kb.cnblogs.com/page/176818/

Jake Boxer 英文博文链接:http://jakeboxer.com/blog/2009/12/13/the-knuth-morris-pratt-algorithm-in-my-own-words/

关于前缀和后缀的定义,这里忽略不提.

一.部分匹配表定义

引用Jake Boxer博文中原句为:The length of the longest proper prefix in the (sub)pattern that matches a proper suffix in the same (sub)pattern.

个人理解为:最长的前缀及其子集与最长的后缀及其子集的匹配结果.

通俗的说:将所有的前缀与其对应的后缀进行比对,将比对结果保存下来,这个表就叫做部分匹配表.

那么部分匹配表是如何计算出来的,下面进行解释

二.计算得到部分匹配表

1.设主串为:abababca 长度为8;

2.将前缀与后缀进行比对:

①子串长度为1时,子串为:a,前后缀不存在,部分匹配表结果为:
|a|b|a|b|a|b|c|a||0|
②子串长度为2时,子串为:ab,前后缀完全相等匹配次数为:0,部分匹配表结果为:前缀为:a;后缀为:b;
|a|b|a|b|a|b|c|a||0|0|
③子串长度为3时,子串为:aba,前后缀完全相等匹配次数为:1,那么此时部分匹配表结果为:前缀为:a;ab;后缀为:a;ba;前缀的a与后缀的a相同,此时完全匹配次数为1;
|a|b|a|b|a|b|c|a||0|0|1|
④子串长度为4时,子串为:abab,前后缀完全像顶匹配次数为:1前缀为:a;ab;aba;后缀为:b;ab;bab;前缀的ab与后缀的ab相同,此时完全匹配次数为:2,理由是:完全匹配的字符串长度为:2
|a|b|a|b|a|b|c|a||0|0|1|2|通过同样的原理,计算其他子串匹配结果,一下为子串长度为7时结果;长度为7的子串:abababc前缀:a;ab;aba;abab;ababa;ababab;
后缀:c;bc;abc;babc;ababc;bababc;完全匹配次数为:0
|a|b|a|b|a|b|c|a||0|0|1|2|3|4|0|最后进行一次完整长度串的匹配:前缀:a;ab;aba;abab;ababa;ababab;abababc;后缀:a;ca;bca;abca;babca;ababca;bababca;完全匹配次数为:1

得到完整的部分匹配表为:
|a|b|a|b|a|b|c|a||0|0|1|2|3|4|0|1|

先给自己立一个Flag,督促自己写KMP算法的学习记录,结束.


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

时间: 2024-08-11 07:42:38

学习记录---KMP算法-部分匹配表理解的相关文章

算法学习笔记 KMP算法之 next 数组详解

最近回顾了下字符串匹配 KMP 算法,相对于朴素匹配算法,KMP算法核心改进就在于:待匹配串指针 i 不发生回溯,模式串指针 j 跳转到 next[j],即变为了 j = next[j]. 由此时间复杂度由朴素匹配的 O(m*n) 降到了 O(m+n), 其中模式串长度 m, 待匹配文本串长 n. 其中,比较难理解的地方就是 next 数组的求法.next 数组的含义:代表当前字符之前的字符串中,有多大长度的相同前缀后缀,也可看作有限状态自动机的状态,而且从自动机的角度反而更容易推导一些. "前

KMP算法的一次理解

1. 引言 在一个大的字符串中对一个小的子串进行定位称为字符串的模式匹配,这应该算是字符串中最重要的一个操作之一了.KMP本身不复杂,但网上绝大部分的文章把它讲混乱了.下面,咱们从暴力匹配算法讲起,随后阐述KMP的流程步骤.next 数组的简单求解.递推原理.代码求解,接着基于next 数组匹配,谈到有限状态自动机,next 数组的优化,KMP的时间复杂度分析,最后简要介绍两个KMP的扩展算法. 2. 暴力匹配算法 2.1 问题描述: 有一个文本串s和一个模式串p,现在要查找p在s中的位置,怎么

KMP算法详解 --- 彻头彻尾理解KMP算法

[经典算法]——KMP,深入讲解next数组的求解 前言 之前对kmp算法虽然了解它的原理,即求出P0···Pi的最大相同前后缀长度k:但是问题在于如何求出这个最大前后缀长度呢?我觉得网上很多帖子都说的不是很清楚,总感觉没有把那层纸戳破,后来翻看算法导论,32章 字符串匹配虽然讲到了对前后缀计算的正确性,但是大量的推理证明不大好理解,没有与程序结合起来讲.今天我在这里讲一讲我的一些理解,希望大家多多指教,如果有不清楚的或错误的请给我留言. 1.kmp算法的原理: 本部分内容转自:http://w

KMP算法的一次理解(中)

在开始KMP算法之前,先来回顾一下字符串模式匹配的暴力法,具体的过程如下图所示: 注:图中两个串的匹配都是从1开始的,代码中的匹配都是从0开始的. 可以看到匹配主串的i的值是不断的回溯的,然而KMP三位大师发现这种回溯其实是不需要的,所以提出来这个算法来解决这个问题. 既然i值不能回溯了,也就是不能变小了,那么要考虑变化的就是j值了.为了能说清楚KMP算法,先以暴力算法为基础分析两个例子. 例1: 主串s="abcdefgab"模式串p="abcdex",也就是上面

KMP算法的一次理解(六)

在前面对KMP算法做了各种的讲解之后,现在要对这个算法做一个代码的实现了: int KmpSearch(char *s, char *p) { int i = 0; int j = 0; int sLen = strlen(s); int pLen = strlen(p); while(i < sLen && j < pLen) { //如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++ if(j == -1 || s[i] == p[j]

KMP算法的一次理解(三)

前面说到了字符串的模式匹配的暴力方法,同时在暴力方法的基础上做了一些改进:不让主串的匹配指针i回溯,通过发掘模式串的一些特性,不断的修改模式串的匹配指针.但是模式串的匹配指针怎么修改呢,那就得要结合其自身的一些特性,然后产生相应的修改值,记录在next[j]这个数组中. 1. 寻找前缀后缀最长公共元素长度: 对于,寻找模式串P中长度最大且相等的前缀和后缀.如果存在 = ,那么在包含pj的模式串中有最大长度为k+1的相同前缀后缀.举个例子,如果给定的模式串为“abab”,那么它的各个子串的前缀后缀

KMP算法的一次理解(上)

在一个大的字符串中对一个小的子串进行定位成为字符串的模式匹配,这应该算是字符串中最重要的一个操作之一了. 问题描述: 有一个文本串s和一个模式串p,现在要查找p在s中的位置,怎么查找? 如果用暴力匹配的思路,并假设文本串匹配到i位置,模式串匹配到j位置. 算法描述: 有关字符串的模式匹配,首先来看最简单的一个算法,那就是暴力法.具体的算法描述: (1)初始化i指向主串的初始位置,这里假设是主串的0位置:j指向子串的0位置. (2)若当前字符匹配成功,也就是s[i] == p[j],则i++,j+

Python 第八阶段 学习记录之---算法

算法(Algorithm): 一个计算过程, 解决问题的方法 1.递归的两个特点 - 调用自身 - 结束条件 时间复杂度 - 时间复杂度是用来估计算法运行时间的一个式子(单位) - 一般来说,时间复杂度高的算法比复杂度低的算法快空间复杂度 用来评估算法内存占用大小的一个式子 列表查找: 从列表中查找指定元素 输入:无序 输出:有序顺序查找: 从列表第一个元素开始,顺序进行搜索,直到找到为止. 二分查找: 从有序列表的候选区data[0:n]开始,通过对待查找的值与候选区中间值的比较,可以使候选区

CCNA 学习记录(三)通过仿真理解ARP协议

拓扑图 配置 路由器R2: GigabitEthernet 0/0/0 IP Address: 192.168.1.1 Subnet Mask: 255.255.255.0 Serial 0/1/0 IP Address: 192.168.1.2 Subnet Mask: 255.255.255.0 PC0: IP Address: 192.168.1.2 Subnet Mask: 255.255.255.0 PC1: IP Address: 192.168.1.3 Subnet Mask: 2