当前位置: 首页 > news >正文

字符串的KMP算法详解及C/C++代码实现

1. 原由

紧接上文,我们知道了暴力匹配的算法在时间运行上的缺陷,假设字符串T的长度为n,字符串P的长度为m,则整个算法的时间复杂度为O( n * m ),而对于一个复杂的现实情况而言 n >> m >> 2 (即n远远大于m,m远远大于常数),这样的计算计算机的负担很重。

请思考一个暴力匹配的情况:

给定一个主字符串

T = “AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB”(47位)

同时给定模式串 P = “AAAAAB”(6位)

试问搜索的情况,很显然,暴力搜索对于每一次搜索,都要搜索到最后一个字符才能进行下一轮的搜索,因此进行的计算近似可以理解为:O(47 * 6) ,对于这样很少的数据已经有很高的计算量了。

KMP算法一种改进的模式匹配算法,是D.E.Knuth、V.R.Pratt、J.H.Morris于1977年联合发表,KMP算法又称克努特-莫里斯-普拉特操作, KMP算法与前文的暴力匹配算法,核心的区别就是没有不匹配的回溯,而是根据整个字符串的情况进行一次位移,这样大大减少了回溯产生的缺陷,KMP算法的时间复杂度可以优化到 O( n + m)级别,是二次优化到线性的程度。

2.构造next表(以-1开头)

对于模式串P而言,我们需要知道模式串中P的每一位的前一位是否存在相等的完全相等的前后缀,并且求这个最大的完全相等的前后缀,如一个模式串”ABCABDE”对于第倒数第二位字符而言,其符合情况的前后缀就是”AB”,而最后一位则没有完全相等的前后缀。

PS:何为前后缀:如一个字符串”ABCD”,其前缀有可能为”A”“AB”“ABC”(即除去本身的全部字符),同理,则后缀可能为:”D””CD””BCD”

我们需要求的就是每一个字符其相对应的最大前后缀数,这样与模式串P一一对应的表称之为next表。

因此”ABCABDE”的next表为:-1 0 0 0 1 2 0 (字符用空格隔开)

那么我们该如何实现代码呢?

对于每一个当前需要判断的字符而言,在构造next表时,应该向前进行比对,以上一个已经判断的情况为基础(初始值赋-1,部分教程中初始值赋0,两者没有实质区别),后缀如果+1位置的字符与前缀+1位置的字符相等,则next[i]就是next[i-1]+1,而如果不相等,则说明无法匹配,则next[i]=0。

3. KMP实现

与暴力匹配极其相似,利用while循环的条件控制, 进行匹配失败时,只需要将失败的模式串P的索引指向next表中对应的数值即可,其余匹配照旧线性执行即可。

4. 实现代码(仅作参考)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;int *buildNext(char *P){int m = strlen(P) , j=0;int * N = new int[m];int t = N[0] = -1;while( j < m-1 ){if( 0 > t || P[j] == P[t] ){N[++j] = ++t;}else{t = N[t];}}return N;
}int KMP(char T[],char P[]){ //T--主串,P--模式串int *next = buildNext(P);   //构造NEXT表int n = strlen(T) , i=0;int m = strlen(P) , j=0;while( j<m && i<n ){if( j<0 || T[i]==P[j] ){i++;j++;}else{j = next[j];}}delete []next;return i-j;
}int main(){char org[] = "ABABABABABD";char str[] = "ABABD";int ans = KMP(org,str);cout << ans <<endl;return 0;
}

输出6,即经过6位,在第七位发生匹配

相关文章:

字符串的KMP算法详解及C/C++代码实现

1. 原由 紧接上文&#xff0c;我们知道了暴力匹配的算法在时间运行上的缺陷&#xff0c;假设字符串T的长度为n&#xff0c;字符串P的长度为m&#xff0c;则整个算法的时间复杂度为O( n * m )&#xff0c;而对于一个复杂的现实情况而言 n >> m >> 2 &#xff08;即…...

2024年数学建模比赛题目及解题代码

目录 一、引言 1. 1竞赛背景介绍 1.1.1数学建模竞赛概述 1.1.2生产过程决策问题在竞赛中的重要性 1.2 解题前准备 1.2.2 工具与资源准备 1.2.3 心态调整与策略规划 二、问题理解与分析 三、模型构建与求解 3.1 模型选择与设计 3.1.1 根据问题特性选择合适的数学模型类…...

BERT 论文逐段精读【论文精读】

BERT: 近 3 年 NLP 最火 CV: 大数据集上的训练好的 NN 模型&#xff0c;提升 CV 任务的性能 —— ImageNet 的 CNN 模型 NLP: BERT 简化了 NLP 任务的训练&#xff0c;提升了 NLP 任务的性能 BERT 如何站在巨人的肩膀上的&#xff1f;使用了哪些 NLP 已有的技术和思想&#xff…...

在Flask中实现跨域请求(CORS)

在Flask中实现跨域请求&#xff08;CORS&#xff0c;Cross-Origin Resource Sharing&#xff09;主要涉及到对Flask应用的配置&#xff0c;以允许来自不同源的请求访问服务器上的资源。以下是在Flask中实现CORS的详细步骤和方法&#xff1a; 一、理解CORS CORS是一种机制&…...

在桌面商业分析应用程序中启用高级 Web UI

挑战 Mercur Business Control 应用程序在企业界&#xff0c;尤其是金融领域&#xff0c;拥有悠久的应用历史。它帮助企业处理、可视化和分析海量数据&#xff0c;从而做出明智的商业决策。 随着产品的不断演进和现代化&#xff0c;Mercur Solutions AB 为该应用创建了 Web 客…...

CentOS Stream 8 通过 Packstack 安装开源 OpenStack(V版)

1、环境规划以及网卡配置 controller IP&#xff1a;192.168.235.101 compute IP&#xff1a;192.168.235.102 控制节点 [rootluck ~]# cd /etc/sysconfig/network-scripts/ [rootluck network-scripts]# vi ifcfg-ens160 [rootluck network-scripts]# cat ifcfg-ens160 TYP…...

OpenSSL工具验证RSA证书

openssl x509 是一个用于处理 X.509 证书的命令行工具。常用的 openssl x509 命令&#xff1a; -in <file>&#xff1a;指定输入文件。-out <file>&#xff1a;指定输出文件。-noout&#xff1a;不输出证书信息。-text&#xff1a;以文本格式输出证书信息。-pubke…...

架构师白话分布式系统

对于分布式系统的定义,大致可以理解为如下的两个点 分布式系统从整体的体量来说,它内部是由很多的服务器、服务实例组成。所提供的用户服务是由一组相互独立运行的服务器来提供。对于用户来说,这个多服务器的系统就跟一个服务器一样,感觉不到每个单独的服务器实例的存在。从…...

C++ 中 vector 的常用功能介绍

在 C 中&#xff0c;vector 是一种常用的动态数组容器&#xff0c;提供了方便的自动扩展、内存管理以及各种便捷的操作方法。它是 C 标准模板库&#xff08;STL&#xff09;的一部分&#xff0c;适用于需要动态存储和管理大量元素的场景。 在本文中&#xff0c;我们将简要介绍…...

[QT] QT事件与事件重写

一.事件 事件(event)是由系统或者 Qt本身在不同的场景下发出的。当用户按下鼠标、敲下键盘&#xff0c;或者是窗口关闭等都会发出一个相应的事件。 一些事件在用户操作时发出(如鼠标/键盘事件); 另一些事件则是由系统自动发出(如计时器事件)。 Qt窗口中对于产生的一系列事件都…...

c# 视觉识别图片文字 二维码

1.二维码识别 插件 ZXing.Net using System; using System.Drawing; // 如果你使用的是System.Drawing.Common using ZXing;class Program {static void Main(){string imagePath "path_to_your_qr_code_image.png";var barcodeBitmap (Bitmap)Image.FromFile(im…...

UEFI——访问PCI/PCIE设备(二)

一、支持访问PCI/PCIE设备的Protocol UEFI中提供了两个主要的模块来支持PCI总线&#xff0c;一是PCI Host Bridge&#xff08;PCI主桥&#xff09;控制器驱动&#xff0c;另一个是PCI总线驱动。这两个模块是和特定的平台硬件绑定的&#xff0c;在这种机制下&#xff0c;屏蔽了…...

决策树算法的介绍与应用

目录 引言 决策树算法的基本原理 表格总结&#xff1a;决策树的构建步骤 决策树算法的 MATLAB 实现 示例&#xff1a;使用决策树进行分类预测 决策树的应用场景 表格总结&#xff1a;决策树的主要应用领域 决策树的优势与局限 结论 引言 决策树是一种广泛应用于数据挖掘…...

杰发科技Bootloader(3)—— 基于7801的APP切到Boot

为了方便在APP中跳转到Boot重新进行升级&#xff0c;有两种办法&#xff0c;7840同样可以使用。 1. 调用reset接口进行复位&#xff0c;复位后会先进Boot&#xff0c;再自动跳转到App。 NVIC_SystemReset(); 2. 直接使用跳转指令&#xff0c;参考Boot跳转到App代码&#xff0…...

Leetcode面试经典150题-138.随机链表的复制

题目比较简单&#xff0c;重点是理解思想&#xff0c;random不管&#xff0c;copy一定要放在next 而且里面的遍历过程不能省略 解法都在代码里&#xff0c;不懂就留言或者私信 /* // Definition for a Node. class Node {int val;Node next;Node random;public Node(int val…...

freemarker模板学习笔记

文章目录 freemarker常用指令if-elseif-else指令switch, case, default, break指令list, else, items, sep, break 指令<#list>指令语法<#else> 指令<#items> 指令<#sep> 指令<#break> 指令 include 指令<#include> 基础知识<#include&…...

高亚科技与广东海悟携手,打造全流程电子竞标管理平台!

近日&#xff0c;中国企业管理软件资深服务商高亚科技与广东海悟科技有限公司&#xff08;以下简称“海悟”&#xff09;正式签署合作协议&#xff0c;双方将基于高亚科技的8Manage SRM系统&#xff0c;推进海悟采购管理的数字化升级&#xff0c;实现全流程在线电子竞标管理&am…...

240908-结合DBGPT与Ollama实现RAG本地知识检索增强

A. 最终效果 B. 背景说明 DBGPT在0.5.6版本中开始支持Ollama&#xff1a;v0.5.6 版本更新 网友对其Web端及界面端的设置进行了分享&#xff1a; feat(model): support ollama as an optional llm & embedding proxy by GITHUBear Pull Request #1475 eosphoros-ai/DB-G…...

AMD ThinkSystem服务器上的 Linux 和 C 状态设置 - Lenovo ThinkSystem

受影响的配置 该系统可以是以下任何Lenovo服务器&#xff1a; ThinkSystem 、SR645&#xff08; ThinkSystem &#xff09;ThinkSystem &#xff0c;SR645 V3&#xff08; ThinkSystem &#xff09;ThinkSystem &#xff0c;SR635 V3&#xff08; ThinkSystem &#xff09;Th…...

Redis过期删除和缓存淘汰

1. 过期删除 在 Redis 中&#xff0c;键的过期删除机制主要包括惰性删除&#xff08;Lazy Deletion&#xff09;和定期删除&#xff08;Periodic Deletion&#xff09;。这两种策略有各自的优缺点&#xff0c;Redis 最终会结合这两种方法来管理过期键。 1.1 惰性删除&#xf…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用

前言&#xff1a;我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM&#xff08;Java Virtual Machine&#xff09;让"一次编写&#xff0c;到处运行"成为可能。这个软件层面的虚拟化让我着迷&#xff0c;但直到后来接触VMware和Doc…...

前端开发者常用网站

Can I use网站&#xff1a;一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use&#xff1a;Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站&#xff1a;MDN JavaScript权威网站&#xff1a;JavaScript | MDN...