今日学习总结--模式匹配算法

AI大模型学习(13)小白也能学会的10分钟豆包大模型的python教程1 豆包AI大模型API是字节跳动推出的智能对话接口服务,开发者可以通过简单的HTTP请求调用强大的AI能力,实现智能问答、内容生成等功能。 阅读详情

模式匹配算法

所谓模式匹配就是在一个主串s中找到子串t的位置,对于复杂的字符串,那么使用怎样的方式去查找就显得尤其重要了。

1、朴素的模式匹配算法
为什么称为朴素呢?因为简单易理解,大家都可以想到,实现起来也相对简单,主要完全可以实现功能。

思路:主串s和子串t都从第一位开始比较,如果相等则比较第二位…如果其中某一位不相等了,则将s回退到i-j+1位置(每次比较一旦遇到不相同,就从开始位置后移一位),j回退到0.(子串又一次从头开始比较)

如下述例子
图1:当比较到第4位发现不相等后,i = i - j +1—> 1
而j = 0; 右开始了新一轮的比较
图2:比较主串第2位的时候,发现不相等,i = i - j +1—> 2
…经过一系列的失败匹配后,移动到了图5
图5:主串从第5开始匹配子串,然后发现全部匹配成功,结束。


以下为实现代码:

#include<iostream>

using namespace std;
//返回子串t在主串t中第pos个字符之后的位置;若不存在,函数返回0
//t非空,1≤pos≤s.size()

int Index(string s, string t){
	int i = 0;
	int j = 0;//两个串都是要从头开始比较
	while (i < s.size() && j < t.size()){
		//一旦有一个串等于了size()要么就是t到头 说明找到了   如果是s到头 说明没有找到
		if (s[i] == t[j]){
			i++;
			j++;
		}
		else{
			i = i - j + 1;//主串位置从开始比较位置后移一位
			j = 0;
		}
	}
	if (j >= t.size()){
		return i - t.size() + 1; //只有子串到头了 才说明找到了
	}
	else{
		return 0;
	}
}

int main()
{
	string s = "goodgoogle";
	string t = "google";
	cout << Index(s, t) << endl;
	return 0;
}

分析一下时间复杂度:

(最坏)具体如
主串是s=“00000000000000000000000000000000000000000000000001”
子串是 t=“00001” 则在比较的过程中,每次都要判断到第五位才能发现不相等 然后又在主串后移一位之后继续比较5次…如此重复,则事件复杂度是O((n-m+1)*m)

基于人类如果在比较的时候,发现前面那些位都是相同的只有某一位不同,就不会在比较前面的,而是直接从不同的那一位开始比较。
因此出现了主串位置不回溯,那么子串应该如何选择最恰当的位置以减少比较次数呢?

2、KMP模式匹配算法

首先假设是这种情况:

因此发现不相同之后,就直接从不相同的位置以及子串第一位开始再次比较。

上面的例子具有特殊性,因为也有可能出现很多子串后面是有相同部分的。

这样,是不是就省去了第4 第5 两个位置的重复比较。

因此,KMP的关键在于比较之前预先遍历子串形成一个next数组

next数组作用:在于当子串和主串出现不相等之后,可以参考next数组,知道j将要回溯到的位置是多少。

如何构建next数组?
首先,第一位的next值为0,第二位的next值为1。联系next数组的功能很容易想到为什么要如此设计前两位的值;
其次,求解每一位的next值时,根据前一位进行比较,使用前一位和他指向的next数组值对应下标的值进行比较,如果相等,那么+1就是当前所求位的next值;
如果出现不等的情况,那就用前一位的next值指向的位置的值的next值指向的位置的值进行比较,如果相等,那么当前所求的next值就是前前位值的next值+1;
如果一直没有找到,当到头之后,所求位值的next就是1.

具体看例子:
例如有一个子串(也叫做模式串) t = "a b a a b c a c " 相应的next值应该是 0 1 1 2 2 3 1 2



有了以上分析相信应该掌握了求解next数组的思想,那么通过下述例子练习一下看看:

由此可以实现KMP算法代码

KMP代码

#include<iostream>
using namespace std;

//通过计算,返回子串的next数组
void get_next(string t, int *next)
{
	int i, j;
	i = 1;
	j = 0;
	next[1] = 0;
	while (i<t.size() - 1)
	{
		if (j == 0 || t[i] == t[j])		//t[i]表示后缀的单个字符,t[j]表示前缀的单个字符
		{
			i++;
			j++;
			next[i] = j;
		}
		else
			j = next[j];			//若字符不相同,则j值回溯
	}

}

//返回子串t在主串t中第pos个字符之后的位置;若不存在,函数返回0
//s[0]和t[0]应该保存字符串的长度,这里我们随意保存一个字符#

int Index_KMP(string s, string t)	
{
	int i = 1;					
	int j = 1;					
	int next[255];					//定义一个next数组
	get_next(t, next);				//对串做分析,得到next数组

	while (i < s.size() && j < t.size())		//若i小于s的长度且j小于t的长度,循环继续
	{
		if (j == 0 || s[i] == t[j])		
		{
			i++;
			j++;
		}
		else					//当发现主串和子串不相等后,主串i位置不回溯,子串通过next数组得到一个合适的位置
			j = next[j];
	}
	if (j >= t.size())
		return i - t.size() + 1;
	else
		return 0;
}

int main()
{
	string s = "#goodgoogle";
	string t = "#google";
	cout << Index_KMP(s, t) << endl;
	return 0;
}

针对以上KMP的一点改进

分析例子:
主串 s = “aaaabcde” 子串 t = “aaaaax” 如果我们使用之前的方法,求出next是 012345 然后我们就会发现执行的过程是

比较时候,当你发现第5位不相等之后,查找next数组拿到j = next[5] = 4, 然后就出现了第2步,接着依然不相等…就有了2 3 4 5 这几步无效的操作。
实际上发现2 3 4 5这几个位置上的值是和第1个位置上的值相等之后,完全可以用第一个位置的next值替代后面的next值,也就是说,不相等之后,直接将j回退到第一位开始比较。

改进后的KMP算法

void get_nextval(string t, int *nextval)
{
	int i, j;
	i = 1;
	j = 0;
	nextval[1] = 0;
	while (i<t.size() - 1)
	{
		if (j == 0 || t[i] == t[j])		
		{
			i++;
			j++;
			if (t[i] == t[j])		//若当前字符与前缀字符相等
			{
				nextval[i] = nextval[j];//将前缀字符的nextval值赋值给nextval在i位置上的值
			}
			else
				nextval[i] = j;		//当前的j为nextval在i位置上的值
		}
		else
			j = nextval[j];			//不相等,j回溯
	}
}

仅仅调整一下 get_nextval函数即可

到此,实现了KMP。分析时间复杂度为 得到next数组的n和后面匹配时候的m,则O(m+n)

更多可关注 sdrzzx2019

C# 从数秒到毫秒:MySQL+Redis百万数据优化实战全解析 在处理百万级数据时,传统单体数据库常面临查询效率低下、数据库负载过高和用户体验差等问题。为解决这些性能瓶颈,可以采用MySQL分库分表、Redis缓存和异步统计的组合策略。 数据库分片:通过水平分表和分库实现,将单表数据分散到多个物理表或数据库实例中,降低单点负载。 Redis缓存:利用Redis缓存高频数据,减少数据库查询压力,提升响应速度。 异步统计:通过消息队列(如RabbitMQ)解耦统计任务,后台处理非实时任务,避免阻塞主流程。 这些优化策略能够显著提升系统性能,确保在高并发和大数据量场景下的稳定 阅读详情

相关推荐

比亚迪璇玑架构:10ms级响应引领智能驾驶革命

比亚迪璇玑架构通过三大创新,实现10ms级控制响应时延,使AEB刹车距离比竞品缩短20米。

百态·数智思维 | 聚焦大数据、量化与未来AI 1256

数据结构与算法总结:字符串(KMP模式匹配算法)

本文总结了数据结构与算法中字符串的主要内容,重点介绍了KMP模式匹配算法

sulfurstar的博客 582

避坑指南:华为2288H-V5服务器安装系统时常见的RAID与驱动问题解决方案

本文针对华为2288H-V5服务器在安装系统时常见的RAID与驱动问题,提供了详细的避坑指南。文章深度解析了从BIOS版本兼容性核查、RAID配置实战到驱动加载与集成的全流程,重点解决了安装过程中因RAID控制器驱动缺失或兼容性问题导致的硬盘无法识别等典型故障,帮助用户高效完成系统部署。

weixin_29240711的博客 979

【3】4 KMP算法思想

KMP 算法: 朴素模式匹配算法的优化! 朴素模式匹配算法缺点: 当某些子串与模式串能部分匹配的时候,主串的扫描指针 i 经常回溯,导致时间开销增加! 分析:oo 都是o 开头,肯定不匹配,然后 g 开头但是紧跟 l 所以也不行, l 开头的也不匹配! 所以不需要像朴素模式匹配算法那样从 g 后面一个一个验证! oogl 开头的不用考虑,那么接下来能够配对上的情况是:如果这个问号是 g,然后后面说不定就是 oogle 呢。 用代码描...

JJL的博客 393

Gemma 4 12B QAT+MTP小显存部署实战指南

大语言模型本地部署的核心瓶颈在于显存与推理效率的平衡。量化感知训练(QAT)通过在训练阶段模拟低精度计算,显著提升模型对INT4量化的鲁棒性;多令牌预测(MTP)则通过并行解码优化KV Cache复用,降低GPU kernel调用频次。二者协同可在8GB显存设备上稳定运行12B级模型,兼顾精度、速度与上下文长度。该方案适用于开发者本地AI助手、技术文档生成、SQL翻译等轻量但高交互需求场景,是当前Windows环境中小显存高效落地Gemma系列模型的工程最优解。

weixin_30934229的博客 376

ArcGIS 10.8软件安装包免费下载及安装教程

ArcGIS 10.8安装教程

qq_44894692的博客 2万+

模式匹配算法--朴素算法

1.朴素的模式匹配算法。 朴素模式匹配算法,简单的说就是循环把主串的每个字符作为开头,与子串去进行匹配。对主串做大循环,每个字符为开头做子串(要匹配的字符串)的小循环,如果对应字符匹配,则两字符串都向后移位,否则子串又从子串的开头开始与主串前一步比较的字符开头的下一位继续匹配,直到匹配成功或(主串)遍历完成。 比如主串为“googldgfegogegoogleglgoogegooglegoo”

但行好事,莫问前程 4193

slew dreate,slew threshold与transition计算

​只看rise情况下,from pin取slew threshold10%-90%的区间,slew derate为1,计算得到transition为1.002e-10,to pin的slew threshold 为30%-70%,slew derate 0.5,从波形列表上取相近的值3.75e-10和8.75e-10,计算得到transition为(8.75e-10-3.75e-10)/0.5=1e-9,考虑精度和取值区间问题,基本符合工具计算的值,如下:​。如下示例,在.lib库中有定义以下内容。

m0_61544122的博客 793

第四章学习小结 串的模式匹配 解题心得体会

串的模式匹配 解题心得体会 关于串,模式匹配是其一个很重要的问题。针对这个问题,书上讲了两种模式匹配的算法,即BF算法和KMP算法,下面针对这两种算法的实现谈谈我的心得。 一、BF算法的探索 【错误代码1】 #include<iostream> #include<string.h> using namespace std; typedef struct{ ...

dianmaju9595的博客 2194

MIPI CPHY学习笔记01:TX物理层一致性测试项解析(LP信令模式)

在手机、平板、智能手表等移动设备中,MIPI C-PHY是负责图像、数据传输的核心接口,它就像设备内部的“高速数据线”,而低功耗(LP)信令模式,是这条“数据线”的“省电模式”,专门用于设备待机、低负载等场景,既要保证信号稳定,又要最大限度降低功耗。物理层一致性测试,就是给这个“省电模式”做的“全面体检”,确保不同厂商的设备能兼容互通。今天,我们就聚焦MIPI C-PHY TX(发射端)的Group 1 LP信令测试,用通俗的语言拆解8个核心测试项,看懂“省电信号”的合格标准。

一只豌豆象的博客 301

苏宁易购手机行情比价系统:构建一个完整的Python爬虫实战指南

在当今数字化时代,智能手机已成为人们生活中不可或缺的一部分。随着各大手机品牌每年推出多款新品,消费者面临着越来越多的选择。然而,不同电商平台、不同时间段的价格波动使得消费者很难把握最佳购买时机。苏宁易购作为国内领先的电商平台之一,拥有丰富的手机商品信息和价格数据。本文将带领读者构建一个完整的苏宁易购手机行情比价系统,帮助消费者实时掌握手机价格动态。

2201_76125261的博客 207

第四章学习小结

关于模式匹配算法,在这里我想总结一下KMP算法。 KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。 然后上下代码: public static int KMP(String ts, String ps) { char[] t ...

diannuoyi8358的博客 174

思博伦仪表打流测试使用总结

下图红框中的checkbox为选中状态时,表示该流会携带测试仪做一些分析,包括时延和乱序等信息时需要的一些字节,当改选项选中时,如配置IPv4的TCP流,最小字节长度必须为78字节;如果需要64字节的TCP流,改选项必须不选中;

陌上花开缓缓归以的博客 1465

JAVA实现KMP模式匹配算法

JAVA实现KMP字符串模式匹配算法

星回昭以烂的博客 452

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

KMP模式匹配算法+ACwing831KMP字符串

题目描述:(来自ACwing) 什么是KMP模式匹配算法呢? 模式匹配算法是很低效的,于是有三位前辈,D.E.Knuth、J.H.Morris、V.R.Pratt发表一个模式匹配算法,可以大大避免重复遍历的情况,我们把它称之为克努特—莫里斯—普拉特算法,简称KMP算法。 朴素模式匹配算法的复杂度是O(N*M),但KMP模式匹配的时间复杂度是O(N),因为n(主串的长度)不需要回溯,要进行匹配的串不停的移动和主串对比,匹配串也不用每次都从头开始比,而是先对匹配串计算出next数组,用next数组..

m0_51474171的博客 211

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

模式匹配的算法Kmp

KMP算法,今天看到一个算法题,然后就突然想到了这个算法,这个算法在大学数据结构中也学了,但是只记得当时自己是百思不得其解,然后是死记硬背的,时至今日必然也抛到九霄云外了,今天重新看的时候也是看了好一会才明白过来算法的经过。就不在说什么理论了,搬上我今天的领会,如果有错误的地方还望指教。 KMP算法的目的就是为了在字符串匹配的时候,不再像传统的暴力匹配那样用了好多无用功。而其核心的地方就

滕米 331

c++ kmp算法字符匹配_一文读懂字符串之 KMP 算法

以前的计算机刚被发明的时候,主要作用是做一些科学和工程的计算工作,科学家发明计算机的时候压根儿不可能想到后人还可以用来KMP。刚开始的计算机都是处理数值工作,后来引入了字符串的概念,计算机开始可以处理非数值的概念了(当然原理还是用数值来模拟非数值,通过ASCII码表)。总之在工作当中字符串的处理操作非常普遍,今日主要分享字符串模式匹配算法KMP的相关操作。在分享KMP算法之前,我们先看一...

weixin_39805355的博客 111

AC算法

转载理由:产品开发中需要高效的字符串匹配算法,所以mark下 转载于:http://blog.youkuaiyun.com/myjoying/article/details/7960534 下一步:学习使用         早在1975年贝尔实验室的两位研究人员Alfred V. Aho 和Margaret J. Corasick就提出了以他们的名字命名的高效的匹配算法---AC算法。该算法

3-Number 2582

KMP算法

前言 对于KMP在几年前自己有了解过,时至今日对其有了更进一步的了解。 网络上有各种各样的关于KMP算法的理解,但是很多阅读起来比较困难,我尝试一种能让自己懂的方式来描述一下这个算法 什么是KMP算法 Knuth-Morris-Pratt 算法(简称 KMP)是解决这一问题的常用算法之一,这个算法是由高德纳(Donald Ervin Knuth)和沃恩·普拉特在 1974 年构思,同年詹姆斯·H·莫里斯也独立地设计出该算法,最终三人于 1977 年联合发表。KMP这个算法名字正是取自这三个人的姓氏首字母。

sinat_30208181的博客 481

字符串多模式匹配:AC算法

早在1975年贝尔实验室的两位研究人员Alfred V. Aho 和Margaret J. Corasick就提出了以他们的名字命名的高效的匹配算法—AC算法。该算法几乎与《KMP算法》同时问世。与KMP算法相同,AC算法时至今日仍然在模式匹配领域被广泛应用。      AC算法是一个经典的多模式匹配算法,可以保证对于给定的长度为n的文本,和模式集合P{p1,p2,…pm},在O(n)时间复杂度

xlxxcc的专栏 2万+

AC算法--多模式匹配(论文解析版)

早在1975年贝尔实验室的两位研究人员Alfred V. Aho 和Margaret J. Corasick就提出了以他们的名字命名的高效的匹配算法---AC算法。该算法几乎与KMP算法(http://blog.youkuaiyun.com/myjoying/article/details/7947119)同时问世。与KMP算法相同,AC算法时至今日仍然在模式匹配领域被广泛应用。          最近本人

myjoying的专栏 1万+

你知道如何从海量字符串中快速找到指定内容吗?

/ 今日科技快讯 /近日,据外媒报道,三星现在正在开发1英寸传感器尺寸的1.5亿像素摄像头,并使用与三星S20 Ultra的ISOCELL Br...

郭霖 1167

【题解】《算法零基础100讲》(第22讲) 字符串算法(二) - 字符串比较(java版)

????算法小白欢迎加入此社区:https://bbs.youkuaiyun.com/forums/hero?category=0 由英雄大佬带领的抱团学算法队伍,从0开始,期待你的加入???? 本博文是对此文章习题所作的题解,如有不足,请多指教:https://blog.youkuaiyun.com/WhereIsHeroFrom/article/details/120875787 今日题解: 第一题:https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/ 第一看想到的

我在人间找bug 825

需掌握的核心算法

一、算法最最基础 1、时间复杂度 2、空间复杂度 二、基础数据结构 1、线性表 列表(必学) 链表(必学) 跳跃表(知道原理、应用,最后自己实现一遍) 并查集(建议结合刷题学习) 2、栈与队列 栈(必学) 队列(必学) 优先队列、堆(必学) 多级反馈队列(原理与应用) 3、哈希表(必学) 碰撞解决方法:开放地址法、链地址法、再次哈希法、建立公共溢出区(必学) 布隆过...

caowx_scut的博客 756

更弱智的算法学习 day9

本文总结了字符串相关算法题的解题思路,重点分析了翻转字符串单词、实现strStr()和重复子字符串检测三类问题。在翻转字符串单词中,提出双指针法和利用split()的简化方案;strStr()问题展示了Python切片的高效实现;重复子字符串检测则给出巧妙的字符串拼接解法。文章还提及右旋字符串的Python简洁实现,并指出KMP算法有待后续补充。这些解法充分利用了Python字符串处理的特性,展示了算法与语言特性结合的高效实践。

qq_53583646的博客 371

【第19天】19c#今日小结

类型转换:把一个类型转成另外一个类型,C#分为显式转换和隐式转换,主要区分点在于需不需要程序员自己写代码进行转换(编译器是否自动转换)、是否存储数据丢失问题。:编译器自动转换,不存在数据丢失场景, (例如值类型把的变量,引用类型场景:把隐式转换规则:1 值类型 小区间往大区间可以直接转换2 引用类型 把子类对象赋值父类的对象3 有符号不能往无符号类型转换。int a = 10;-----编译器自动转换-----数据没有丢失首先定义两个类,一个基类一个派生类。

LL9753的博客 1293

AC多模匹配算法

总结:AC算法的核心是三张查找表:goto、failure和output,共包含四种具体的算法,分别是计算三张查找表的算法以及AC算法本身。可以先阅读博客(http://tech.meituan.com/ac.html)了解goto表、failure表。 下述文章(http://blog.youkuaiyun.com/myjoying/article/details/7960534)博客转发。早在1975年贝

《我是你的正能量》 2661
上一篇: 浅谈C/C++中的static关键字
下一篇: 求两个有序数组的上中位数O(logN)
Rany010
博客等级 码龄9年 5粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值