【算法篇】KMP算法,一种高效的字符串匹配算法

我们今天了解一个字符串匹配算法-KMP算法,内容难度相对来说较高,建议先收藏再细品!!!
在这里插入图片描述

KMP算法的基本概念

KMP算法是一种高效的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。

该算法的主要使用场景就是在字符串(也叫主串)中的模式串(也叫字串)定位问题,常见的有“求子串出现的起始位置”、“求子串的出现次数”等。

解决什么问题

假设有两个字符串,分别为文本串和模式串,如下:


求在文本串中是否出现过上面的模式串。

暴力解法

当出现不匹配的字符时,暴力算法会进行如下两个操作:

  • 向后移动模式串
  • 目标串和模式串的指针都回溯

KMP优化解法

使用暴力算法的时间复杂度较高,如何去优化呢?

优化方向:防止或减少主串指针回溯

当出现不匹配的字符时,目标串指针不动,只移动模式串。

移动前,指针左边的字符已经匹配了,所以要让移动后的目标串的指针不会苏,需要保证:模式串移动之后,在指针左边的字符也是匹配的。

  • 找相同字符必须是从模式串第一个位置开始
  • 模式串移动方式由能找到的最长的相同字符决定,如果不是最长的,可能会漏掉能匹配的内容。
  • 找到的最长的相同字符串长度必须小于已经匹配的内容长度,前后部分可以有交叉内容

KMP算法小结

  • 发生不匹配时,指针所指的下标等于已经匹配的长度
  • 发生不匹配时,需要移动的长度 = 已经匹配的长度 - 前后相同的最大长度
  • 前后相同的最大长度为空的地方用-1补齐

KMP算法中的next数组

当目前的C和A不匹配时,由于A的前面也全都是A,所以前面也一定不匹配,对于这个模式串,可以直接将指针移动到-1的位置。

所以需要再对next数组进行改进,改进后的数组我们命名为nextval。

优化next数组

总结:若str[j] == str[next[j]],那么nextval[j] = nextval[next],否则nextval[j] = next[j]

判断是否匹配

先给定两个字符串,分别表示文本串和模式串,通过kmp(稍后写这个函数)进行比较,找到第一次出现模式串的位置,如果没有匹配上则给出提示。

char *text = "aaaaaabaaa",*pattern = "aaaab";
int index = kmp(text,pattern);
if(index == -1)
{
	cout << "没有匹配上内容";
} 
else{
 	cout << "匹配上了,起始位置为:" << index;
}

输出next数组

next指针用来动态获取模式串的长度

int kmp(char *text,char *pattern){
	int index = -1;
	int txt_len = strlen(text),ptn_len = strlen(pattern);
	int *next = (int *)malloc(sizeof(int) * ptn_len);
	get_next(pattern,next,ptn_len);

	free(next);
	return index;
}

计算next数组

若str[j] == str[k]时,next[j+1] = k+1
若str[j] != str[k]时,k = next[k]

void get_next(char *str,int *next,int len){
	int j = 0,k = -1;
	next[0] = -1;
	while(j < len-1){
		if(k == -1 || str[j] == str[k]){
			k++;
			j++;
			next[j] = k;
		}
		else k = next[k];
	} 
}

遍历输出next数组

从下标为0的位置到ptn_len依次输出next数组内的元素

int kmp(char *text,char *pattern)
{
	int index = -1;
	int txt_len = strlen(text),ptn_len = strlen(pattern);
	int *next = (int *)malloc(sizeof(int) * ptn_len);
	get_next(pattern,next,ptn_len);
	
	for(int i=0;i<ptn_len;i++){
		printf("%d ",next[i]);
	}
	
	free(next);
	return index;
}

输出nextval数组

将next数组变为nextval数组(此处的next数组实际上是nextval数组)

if(k == -1 || str[j] == str[k]){
	k++;
	j++;
	if(str[j] == str[k]){
		next[j] = next[k];
	}
	else{
		next[j] = k;
	}
}
else{
	k = next[k];
} 

输出匹配位置

int index = -1,txt_idx = 0,ptn_idx = 0;
... ...
get_next(pattern,next,ptn_len);

while((txt_idx < txt_len) && (ptn_idx < ptn_len))
{
	if(text[txt_idx] == pattern[ptn_idx] || ptn_idx == -1){
		txt_idx++;
		ptn_idx++;
	}
	else{
		ptn_idx = next[ptn_idx];
	}
}

if(ptn_idx >= ptn_len){
	index = txt_idx - ptn_len;
}

利用KMP算法解决字符串匹配问题,能极大节约时间复杂度。关于KMP算法还有什么问题的话,欢迎各位留言交流~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SPI协议——对外部SPI操作(跨页读写)

关于W25Q32JVSSIQ的详细内容在之前的两篇文章中已经详细介绍&#xff0c;本文不做太多赘述&#xff0c;如果对芯片的了解有缺失的话&#xff0c;可以参考&#xff1a; SPI协议——对外部SPI Flash操作-CSDN博客 SPI协议——读取外部SPI Flash ID_spi flash 读取id-CSDN博客 目录…

快手矩阵管理系统:引领短视频运营新潮流

在短视频行业蓬勃发展的今天&#xff0c;如何高效运营和优化内容创作已成为企业和创作者关注的焦点。快手矩阵管理系统以其强大的核心功能&#xff0c;为短视频内容的创作、发布和管理提供了一站式解决方案。 智能创作&#xff1a;AI自动生成文案 快手矩阵管理系统的智能创作…

如何快速将Excel定义的表结构转换为MySQL的建表语句

目录 引言 方法一&#xff1a;使用Python编程 步骤一&#xff1a;安装必要的库 步骤二&#xff1a;读取Excel文件 步骤三&#xff1a;编写函数生成建表语句 注意事项 方法二&#xff1a;使用Excel VBA 步骤一&#xff1a;启用VBA编辑器 步骤二&#xff1a;编写VBA代码…

随手记录: Ubuntu NVIDIA显卡驱动安装后 屏幕亮度无法调节 无法连接外显示器等问题

背景 一句话&#xff1a;简单记录帮身边人装系统发现 GPU和外接显示器的无法连接&#xff0c;同时亮度无法调节等新问题 设备型号&#xff1a; 联想笔记本&#xff1a;ThinkBook 16p Gen2CPU&#xff1a;AMD Ryzen 7 5800HGPU&#xff1a;RTX 3060 问题描述及流程&#xff…

金蝶API取数+JSON解析,FDL助力高效数据处理

目录 一、企业介绍 二、业务难题与挑战 商管预算管理瓶颈凸显&#xff1a;金蝶数据手工导出&#xff0c;跨库关联分析时效受限 金蝶API数据提取&#xff1a;挑战重重的技术攻坚战 三、解决方案 商管预算管理升级&#xff1a;API取数JSON解析&#xff0c;FineDataLink助力高效数…

文华财经多空波段均线交易黄金分割线指标公式源码

文华财经多空波段均线交易黄金分割线指标公式源码&#xff1a; 多:EMA(C,3),COLORYELLOW; 空:EMA(C,5),COLOR00FF00; 均衡:EMA(空,5),COLORWHITE; VARF1:COUNT(CROSS(多,均衡),2)1; VARF2:COUNT(CROSS(空,均衡),2)1; ZAI:FILTER(VARF1 AND VARF2,2); DRAWTEXT(ZAI,均衡*…

Java基础回顾

1.一个Java程序有且仅有一个main方法作为程序的入口 由main方法所关联的 2.权限修饰符 修饰类 修饰方法 修饰域 public 都可以访问 都可以访问 都可以访问 protected 不能修饰类 子类可以继承&#xff0c;可以访问&#xff0c;同包下的类也可以访问。可以直接访问父…

JNPF-V5.x重磅来袭!

背景概述 行业背景 低代码⾏业经过⼏年的发展、沉淀&#xff0c;其产品的能⼒定位已逐渐清晰&#xff0c;低代码的核⼼价值是提升专业开发 ⼈员的效率&#xff0c;更便捷的调⽤多种能⼒的接⼝&#xff0c;适合IT能⼒强、IT背景复杂的企业使⽤。同时在客户认知层 ⾯上也以⽇…

【Sql Server】sql server 2019设置远程访问,外网服务器需要设置好安全组入方向规则

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》。 这是《Sql Server》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言1、无法链接…

股票分析系统设计方案大纲与细节

股票分析系统设计方案大纲与细节 一、引言 随着互联网和金融行业的迅猛发展,股票市场已成为重要的投资渠道。投资者在追求财富增值的过程中,对股票市场的分析和预测需求日益增加。因此,设计并实现一套高效、精准的股票分析系统显得尤为重要。本设计方案旨在提出一个基于大…

Redis基础教程(十五):Redis GEO地理信息查询与管理

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

Leetcode—97. 交错字符串【中等】

2024每日刷题&#xff08;140&#xff09; Leetcode—97. 交错字符串 2d动规实现代码 class Solution { public:bool isInterleave(string s1, string s2, string s3) {int m s1.length();int n s2.length();int len s3.length();if(m n ! len) {return false;}vector<…

从零开始做题:easycap

题目 给出一个pcap文件 解题 注&#xff1a;传输控制协议&#xff08;TCP&#xff0c;Transmission Control Protocol&#xff09;是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议 .pcap文件需要用Wireshark打开 用Wireshark打开easycap.pcap文…

详解IPXProxy海外代理与Morelogin指纹浏览器集成使用策略

在进行网络活动时&#xff0c;安全性是用户关注的重点。Morelogin指纹浏览器能够创建并管理多个独立的浏览器环境&#xff0c;每个环境都拥有独特的设置&#xff0c;这样用户在登录时可以拥有不同的身份。然而想要避免平台的检测&#xff0c;海外代理IP是必不可少的工具&#x…

代码随想录-Day53

739. 每日温度 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 示例 1: …

【渗透测试】利用hook技术破解前端JS加解密 - JS-Forward

前言 在做渗透测试项目时&#xff0c;尤其是金融方面&#xff0c;经常会遇到前端JS加解密技术&#xff0c;看着一堆堆密密麻麻的密文&#xff0c;会给人一种无力感。Hook技术则会帮助我们无需获取加解密密钥的前提下&#xff0c;获取明文进行渗透测试 环境准备 JS-Forward Burp…

(附源码)c#+winform实现远程开机(广域网可用)

实现逻辑 利用UDP协议发送特定格式的魔术包&#xff0c;以远程唤醒具有特定MAC地址的目标计算机。目标计算机的BIOS和网络配置需要支持Wake-on-LAN&#xff08;WOL&#xff09;功能&#xff0c;并且需要在目标计算机上配置正确的网络唤醒设置。 源码在最后 准备工作 进入Bio…

NB!小哥竟然绕过了安全启动,Dump了SoC的BootROM。

原文&#xff1a;Amlogic S905 SoC: bypassing the (not so) Secure Boot to dump the BootROM译者&#xff1a;TrustZone 推荐语&#xff1a; 这是一篇关于如何绕过安全启动&#xff0c;然后实现破解BootRom的文章。通过这篇文章&#xff0c;可以让你对于ATF、安全启动等有个…

快人一步:预防勒索病毒的利器

在当今日益复杂的网络安全环境中&#xff0c;各种病毒、勒索软件层出不穷&#xff0c;对个人电脑、企业服务器甚至国家信息安全构成严重威胁。而白名单可信机制作为一种有效的安全防护手段&#xff0c;在防勒索病毒中发挥着至关重要的作用。 一、白名单可信机制概述 白名单可信…

3Python的Pandas:数据选取

1.数据选取操作 1.1. 选取单列 df[Q1]df[Q2]1.2. 选取多列 df[[team,Q1]]df.loc[:,[team,Q1]]1.3.选择行 使用指定索引选择 df[df.indexAck]选择前n行 df[0:3]df.iloc[:10,:]1.4. 前n行&#xff0c;每隔m选择一个 df[0:10:3]1.5. 条件选择 df[df.Q1>90]df[(df.teamC…