KMP超高效匹配算法

简介:

        KMP算法是一种改进的字符串匹配算法,其中,KMP算法的运用核心是利用匹配失败后的信息,最大进度的减少模式串与目标串的匹配次数以达到快速匹配的效果。算法与暴力求解的改进在于每当一趟匹配过程中出现的字符比较不相等时,指向目标串的指针不在回到"原点",而是利用已经得到的”部分匹配“的结果将模式串向右移动最大且和目标串已匹配的距离后进行比较,总的来说就是目标串不回退,模式串回退,直到结束为止。

KMP实现如图:

        在图中,第一次比较不成功时,i= 3,j = 3,此时,i指针不变,需要将模式串向右移动两个字符的位置,继续进行i = 3,j = 1的下一趟比较;第二趟匹配中,前四个字符比较成功,但i = 7, j = 5时比较失败,此时将模式串向右移动3个字符的位置,继续进行i = 7,j = 2的下一趟比较,直至比较成功。

        注意,在整套算法体系中,指向目标串的指针i不会退,因此,一旦模式串在某个位置匹配失败后就要回退到某个位置与目标串继续进行匹配。


模式匹配:

        然而,在此,我们可发现,KMP算法中难点就在于模式串在匹配失败后要回退的位置。

        目标串的每个元素都要进行模式匹配,因此,当模式串的每个元素都有一个回退某个具体位置的指标,我们用next整型数组进行存储,即next[j] = k(j模式串的具体位置,k 为回退到模式串的具体位置)。

其中,k的值是这样规定的:

        1,规则:找到匹配成功部分的两个相等的真子串(注意:不包含本身,因为本身还要进行匹配),一个以下标0开始,另一个以j - 1下标结尾,即模式串的头部和尾部(原因可思考一下)。

        2,不管什么数据next[0] = -1;next[1] = 0;在这里,我们以下标来开始,而说到的第几个是从1开始。

下面我们运用以上原理来求模式串的next数组:

        


       以上的定位数组next的定位一定要根据模式串与目标串前后匹配成功的最大次数来定,而具体的匹配是根据模式串的前面和目标串的某个可以与之匹配的最大次数。

        到这里,我们手动求解定位数组next问题不大,那么,接下来要怎么用代码来求解呢?首先,我们先来观察已知条件,在求解next[i + 1]中,我们已知next[i]  = k;如果我们能够通过next[i]的值,再根据数学转换得到next[i + 1]的值,那么就能够实现整个数组的内容。

        首先,已知数组next[i] = k成立,具体的实现next数组我用图形的形式跟大家来演示:

接下来我用C代码的形式来演示一遍定位数组的求解:

//next代表定位数组,a代表模式串,lena代表模式串的长度
void Next(int* next, char* a, int lena)
{next[0] = -1;next[1] = 0;int j = 2, k = 0;while (j < lena) {if (k == -1 || a[k] == a[j - 1]) {next[j] = k + 1;j++;k++;}else{k = next[k];}}
}

        其中,定位数组算法的时间复杂度效率为O(lena)

具体运用代码如下:

int KMP(char* str, int strlen, char* a, int alen, int* next)
{assert(strlen || alen);int i = 0, j = 0;while (i < strlen && j < alen) {//匹配成功,进行下一步if (j == -1 || str[i] == a[j]) {i++;j++;}//当不满足匹配时,进行回退,直到匹配成功为止else {j = next[j];}}//模式匹配成功if (j == alen) {return i - j + 1;}//模式匹配失败else {return -1;}
}

补:部分书籍KMP高效匹配可能有些不同,但基本思路都相同,此算法的效率很高,时间复杂度为O(alen + strlen).

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/128740.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Django创建应用、ORM的进阶使用及模型类数据库迁移

1 Django项目创建第一个应用 Django 项目就是基于 Django 框架开发的 Web 应用&#xff0c;它包含了一组配置和多个应用&#xff0c;我们把应用称之为 App&#xff0c;在前文中对它也做了相应的介绍&#xff0c;比如 auth、admin&#xff0c;它们都属于 APP。 一个 App 就是一…

postman token 请求头添加

思路&#xff1a; 1、登录成功后将 得到的token设置为集合变量 2、在需要携带Authorization的请求头上使用该集合变量 关键代码 const responseData pm.response.json(); if(responseData.code 1) {// 获取tokenconst {data:{token}} responseData// 设置为集合变量pm.colle…

C# 实现电子签名

本项目基于Emgu.CV&#xff08;C#下OpenCv的封装&#xff09;开发的&#xff0c;编译器最新版Vs2022&#xff0c;编译环境x86 直接看效果图 1.主页面 2.我们先看手写的方式&#xff1a; 点击确认就到主界面&#xff0c;如下 &#xff1a; 点击自动适配-&#xff0c;再点击生成…

《C++设计模式》——创建型

前言 创建型为了创建东西才是有用的&#xff0c;创建型设计模式使用的场景&#xff1a; 1、创建一个东西&#xff1b; 2、可重复利用&#xff1b; 3、灵活性高&#xff0c;代码可因地制宜。 Factory Method(工厂模式) 工厂模式将目的将创建对象的具体过程屏蔽隔离起来&#…

go channel实践与源码探索(初始化、发送消息、接收消息、关闭)

文章目录 概要一、并发编程1.1、Actor模型1.2、CSP模型 二、Go Channel实践三、源码分析3.1、初始化3.2、发送消息3.3、接收消息3.4、关闭通道 总结 概要 通道&#xff08;Channel&#xff09;是Go语言提供的协程之间通信与同步的方式。我们知道在并发编程&#xff08;多进程、…

时序分解 | MATLAB实现北方苍鹰优化算法NGO优化VMD信号分量可视化

时序分解 | MATLAB实现北方苍鹰优化算法NGO优化VMD信号分量可视化 目录 时序分解 | MATLAB实现北方苍鹰优化算法NGO优化VMD信号分量可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 北方苍鹰优化算法NGO优化VMD&#xff0c;对其分解层数&#xff0c;惩罚因子数做优化…

基于Python开发的玛丽大冒险小游戏(源码+可执行程序exe文件+程序配置说明书+程序使用说明书)

一、项目简介 本项目是一套基于Python开发的玛丽冒险小游戏程序&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Python学习者。 包含&#xff1a;项目源码、项目文档等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xf…

Alibaba(商品详情)API接口

为了进行电商平台 的API开发&#xff0c;首先我们需要做下面几件事情。 1&#xff09;开发者注册一个账号 2&#xff09;然后为每个alibaba应用注册一个应用程序键&#xff08;App Key) 。 3&#xff09;下载alibaba API的SDK并掌握基本的API基础知识和调用 4&#xff09;利…

管理类联考——数学——汇总篇——知识点突破——应用题——交叉比例法/杠杆原理

读书笔记 甲有&#xff1a;x个a&#xff0c;乙有&#xff1a;y个b&#xff0c;甲乙的平均值为c&#xff0c;根据总数相等&#xff0c;得&#xff1a;axbyc(xy)&#xff0c;即ax-cxcy-by&#xff0c;则 x y c − b a − c \frac{x}{y}\frac{c-b}{a-c} yx​a−cc−b​ &#…

OpenCV(二十五):边缘检测(一)

目录 1.边缘检测原理 2.Sobel算子边缘检测 3.Scharr算子边缘检测 4.两种算子的生成getDerivKernels() 1.边缘检测原理 其原理是基于图像中灰度值的变化来捕捉图像中的边界和轮廓。梯度则表示了图像中像素强度变化的强弱和方向。 所以沿梯度方向找到有最大梯度值的像素&…

17-数据结构-查找-(顺序、折半、分块)

简介&#xff1a;查找&#xff0c;顾名思义&#xff0c;是我们处理数据时常用的操作之一。大概就是我们从表格中去搜索我们想要的东西&#xff0c;这个表格&#xff0c;就是所谓的查找表&#xff08;存储数据的表&#xff09;。而我们怎么设计查找&#xff0c;才可以让计算机更…

sqli-labs关卡之一(两种做法)

目录 一、布尔盲注(bool注入) 二、时间盲注(sleep注入) 一、布尔盲注(bool注入) 页面没有报错和回显信息&#xff0c;只会返回正常或者不正常的信息&#xff0c;这时候就可以用布尔盲注 布尔盲注原理是先将你查询结果的第一个字符转换为ascii码&#xff0c;再与后面的数字比较…

Redis带你深入学习数据类型set

目录 1、set 2、set相关命令 2.1、添加元素 sadd 2.2、获取元素 smembers 2.3、判断元素是否存在 sismember 2.4、获取set中元素数量 scard 2.5、删除元素spop、srem 2.6、移动元素smove 2.7、集合中相关命令&#xff1a;sinter、sinterstore、sunion、sunionstore、s…

mac电脑安装paste教程以及重新安装软件后不能使用解决方法

问题背景 mac电脑安装paste教程以及重新安装软件后不能使用解决方法。 mac电脑安装paste失败&#xff0c;安装好后还是无法使用&#xff0c;paste显示还是历史粘贴信息&#xff0c;导致无法使用。新 copy的内容也无法进入历史粘贴版里面。 笔者电脑配置信息&#xff1a;MacB…

【算法与数据结构】501、LeetCode二叉搜索树中的众数

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;根据前面几篇文章98、LeetCode验证二叉搜索树、530、LeetCode二叉搜索树的最小绝对差。我们知道二叉搜…

Boost搜索引擎

项目背景 先说一下什么是搜索引擎,很简单,就是我们平常使用的百度,我们把自己想要所有的内容输入进去,百度给我们返回相关的内容.百度一般给我们返回哪些内容呢?这里很简单,我们先来看一下. 搜索引擎基本原理 这里我们简单的说一下我们的搜索引擎的基本原理. 我们给服务器发…

Selenium - Tracy 小笔记2

selenium本身是一个自动化测试工具。 它可以让python代码调用浏览器。并获取到浏览器中加们可以利用selenium提供的各项功能。帮助我们完成数据的抓取。它容易被网站识别到&#xff0c;所以有些网站爬不到。 它没有逻辑&#xff0c;只有相应的函数&#xff0c;直接搜索即可 …

基于SSM的精品酒销售管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Linux平台如何实现采集音视频数据并注入轻量级RTSP服务?

技术背景 好多开发者&#xff0c;问我们最多的问题是&#xff0c;为什么要设计轻量级RTSP服务&#xff1f;轻量级RTSP服务&#xff0c;和RTSP服务有什么区别&#xff1f; 针对这个问题&#xff0c;我们的回答是&#xff1a;轻量级RTSP服务解决的核心痛点是避免用户或者开发者…

MSTP + Eth-Trunk配置实验 华为实验手册

1.1 实验介绍 1.1.1 关于本实验 以太网是当今现有局域网LAN&#xff08;Local Area Network&#xff09;采用的最通用的通信协议标准&#xff0c;以太网作为一种原理简单、便于实现同时又价格低廉的局域网技术已经成为业界的主流。 本实验主要介绍了LAN网络中的Eth-Trunk技术…