【字符串匹配算法】BF与KMP算法

一、BF算法

1.1 概念

BF算法,即暴力(Brute Force)算法,是普通的模式匹配算法,BF算法的思想就是将目标串S与字串T的第一个字符进行匹配,若相等,则继续比较S的第二个字串和T的第二个字符;如不相等,则比较S的第二个字符和T的第一个字符,依次比较下去,直到得出最后的匹配结果。BF算法的时间复杂度位为O(n*m)。

1.2 实现

int BF(const char* str, const char* sub)
{
	//检查
	assert(str && sub);
	int lenstr = strlen(str);
	int lensub = strlen(sub);
	assert(lenstr && lensub);

	int i = 0;
	int j = 0;
	while( i < lenstr&&j<lensub)
	{
		//相等就比较下一个
		if (str[i] == sub[j])
		{
			i++;
			j++;
		}
		//不相等就将i变到比较的下一个,j归零
		else
		{
			i = i - j + 1;
			j = 0;
		}
	}
	
	//判断子串是否结束
	if (j == lensub)
		return i - j;
	else
		return -1;
}

二、KMP算法

2.1 概念

KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP的时间复杂度位O(m+n)。
区别:KMP和BF唯一不一样的地方在于KMP主串的i并不会回退,并且j也不会移动到0号位置

2.2 理解

在这里插入图片描述
首先,字符串”BBC ABCDAB ABCDABCDABDE”的第一个字符与搜索词”ABCDABD”的第一个字符,进行比较。因为B与A不匹配,所以搜索词后移一位。
在这里插入图片描述
因为B与A不匹配,搜索词再往后移。
在这里插入图片描述
就这样,直到字符串有一个字符,与搜索词的第一个字符相同为止。
在这里插入图片描述
接着比较字符串和搜索词的下一个字符,还是相同。
在这里插入图片描述
直到字符串有一个字符,与搜索词对应的字符不相同为止。
当空格与D不匹配时,你其实知道前面六个字符是”ABCDAB”。KMP算法的想法是,设法利用这个已知信息,不要把”搜索位置”移回已经比较过的位置,继续把它向后移,这样就提高了效率。
在这里插入图片描述
因为空格与C不匹配,搜索词还要继续往后移。

在这里插入图片描述
逐位比较,直到发现C与D不匹配。于是,继续将搜索词向后移动。
在这里插入图片描述
逐位比较,直到搜索词的最后一位,发现完全匹配,于是搜索完成。

2.3 next()数组

接下来我们来看这么一个子串,推导出它的next()数组:
在这里插入图片描述

KMP算法精髓就在于next()数组:也就是next[j] = k; 来表示,不同的j对应一个k值,这个k就是你将来要移动的j要移动的位置。

K值的规则

  1. 规则:找到匹配成功部分的两个相等的真子串(不包含本身),一个以下标0字符开始,另一个j-1下标字符结尾。
  2. 不管什么数据next[0] = -1;next[1] = 0;。

2.4 实现

void getnext(char* next, const char* sub)
{
	next[0] = -1;
	next[1] = 0;
	
	int i = 2, k = 0;
	int len = strlen(sub);
	while (i < len)
	{
		if (k==-1||sub[k] == sub[i - 1])
		{
			next[i] = k + 1;
			i++;
			k++;
		}
		else
		{
			k = next[k];			
		}
	}
}

int KMP(const char* str, const char* sub, int pos)
{
	//检查
	assert(str && sub);
	int lenstr = strlen(str);
	int lensub = strlen(sub);
	assert(lenstr && lensub);
	
	char* next = (char*)malloc(sizeof(char) * lensub);
	getnext(next, sub);

	int i = 0, j = 0;
	while (i < lenstr && j < lensub)
	{
		if (j==-1||str[i] == sub[j])
		{
			i++;
			j++;
		}
		else
		{
			j = next[j];
		}
	}

	free(next);
	if (j == lensub)
		return i - j;
	else
		return -1;
}

2.5 nextval()数组

在这里插入图片描述

这里提一句:本篇博客求出的nextval或next值可能与参考答案差一,加一即可,具体体现在函数实现上。

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

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

相关文章

【Allure】allure装饰器函数

**allure装饰器**​作用&#xff1a;用于将测试用例的数据展示到测试报告中 1.需要将这些装饰器函数添加**测试方法或测试类的开头**。2.同一个类或者一个方法可以添加多个装饰器函数 &#xff0c;这样此用例就具有了个作用属性 。 allure.epic() 敏捷中的概念 项目名称 allu…

1.3 自然语言处理的应用

自然语言处理&#xff08;NLP&#xff09;在多个领域有广泛应用&#xff0c;如自动文摘、机器翻译、情感分析等。本实战将通过NLTK库&#xff0c;演示文本预处理的关键技术&#xff0c;包括小写转换、去噪、文本规范化、词干提取、词形还原、标记化以及删除停止词。这些技术为构…

数学建模启发式算法篇(一)---遗传算法

文章目录 1.引言2.生物学基础2.1适应度2.2染色体&#xff0c;基因 3.算法介绍3.1算法流程3.2编码和解码3.3轮盘赌选择3.4交叉和变异3.5初始参数的设置 4.实际应用-matlab4.1观察图像4.2初始参数说明4.3init初始化4.4二进制转换为十进制4.5选择,交叉过程4.6情况说明4.7代码 1.引…

Matplotlib | 条形图中的每个条形(patch)设置标签数据的方法

方法一 不使用子图对象如何给形图中的每个条形设置数据 plt.figure(figsize(8, 4)) sns.countplot(xWorkout_Frequency (days/week), datadf)plt.title(会员每周锻炼频率分布) plt.xlabel(锻炼频率 (每周次数)) plt.ylabel(人数)# 获取当前活动的轴对象 ax plt.gca()# 循环遍…

【JavaSE】(2) 方法

一、认识方法 1. 方法的定义 修饰符 返回类型 方法名(形参类型 形参名, ......){......return 返回值; } 示例代码&#xff1a; 2. 方法的作用 增强代码的可复用性。&#xff08;避免重复造轮子&#xff09;增强代码的易管理性。&#xff08;改方法就行&#xff0c;不用到处…

计算机网络socket编程(1)_UDP网络编程实现echo server

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 计算机网络socket编程(1)_UDP网络编程实现echo server 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记&#xff0c;欢迎大家在评论区交…

第9章 Apache WEB服务器企业实战

万维网 (WORLD WIDE WEB,WWW)服务器,也称之为WEB服务器,主要功能是提供网上信息浏览服务。WWW是 Internet的多媒体信息查询工具,是Internet上飞快发展的服务,也是目前用的最广泛的服务。正是因为有了WWW软件,才使得近年来 Internet 迅速发展。 目前主流的WEB服务器软件包…

C++__XCode工程中Debug版本库向Release版本库的切换

Debug和Release版本分别设置编译后&#xff0c;就分别得到了对应的lib库&#xff0c;如下图&#xff1a; 再生成Release后如下图&#xff1a;

关于圆周率

关于圆周率 大约20年前的2005年&#xff0c;我在上大学的时候&#xff0c;网上流传这样一段程序&#xff0c;被称之为“外星人计算圆周率程序”。程序如下&#xff1a; long a 10000, b, c 2800, d, e, f[2801], g; main() {for (; b - c;) f[b] a / 5; for (; d 0, g …

Node.js回调函数以及事件循环使用介绍(基础介绍 三)

回调函数 Node.js 异步编程的直接体现就是回调。 异步编程依托于回调来实现&#xff0c;但不能说使用了回调后程序就异步化了。 回调函数在完成任务后就会被调用&#xff0c;Node 使用了大量的回调函数&#xff0c;Node 所有 API 都支持回调函数。 例如&#xff0c;我们可以…

TIDB的结构

tidb主要由三部分组成&#xff1a; 1、tikv tikv是tidb中存储数据的地方&#xff0c;以key-value格式存储&#xff0c;每一行对应一个key&#xff1b; (1)、table的key对应格式如下&#xff1a;tablePrefix{tableID}_recordPrefixSep{rowID}&#xff0c;tableID是唯一的、rowID…

深度学习基础知识-编解码结构理论超详细讲解

编解码结构&#xff08;Encoder-Decoder&#xff09;是一种应用广泛且高效的神经网络架构&#xff0c;最早用于序列到序列&#xff08;Seq2Seq&#xff09;任务&#xff0c;如机器翻译、图像生成、文本生成等。随着深度学习的发展&#xff0c;编解码结构不断演变出多种模型变体…

【初阶数据结构】实现顺序结构二叉树->堆(附源码)

文章目录 须知 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助吗&#xff1…

CSS基础学习篇——选择器

学习文档连接&#xff1a;CSS层叠样式表 1.全局选择器&#xff1a;* * {margin: 0;padding: 0;font-size: 18px; }2.类&#xff08;clss&#xff09;选择器&#xff0c;以 . 开头 .container {display: flex;justify-content: space-around;align-items: center;width: 1200…

shodan(五)连接Mongodb数据库Jenkinsorg、net、查看waf命令

声明&#xff1a;学习素材来自b站up【泷羽Sec】&#xff0c;侵删&#xff0c;若阅读过程中有相关方面的不足&#xff0c;还请指正&#xff0c;本文只做相关技术分享,切莫从事违法等相关行为&#xff0c;本人一律不承担一切后果 引言&#xff1a; 1.Shodan 是一个专门用于搜索连…

探索PickleDB:Python中的轻量级数据存储利器

文章目录 探索PickleDB&#xff1a;Python中的轻量级数据存储利器1. 背景&#xff1a;为什么选择PickleDB&#xff1f;2. PickleDB是什么&#xff1f;3. 如何安装PickleDB&#xff1f;4. 简单的库函数使用方法创建和打开数据库设置数据获取数据删除数据保存数据库 5. 应用场景与…

高效自动化测试,引领汽车座舱新纪元——实车篇

引言 作为智能网联汽车的核心组成部分&#xff0c;智能座舱不仅是驾驶者与车辆互动的桥梁&#xff0c;更是个性化、智能化体验的源泉。实车测试作为验证智能座舱功能实现、用户体验、行车安全及法规符合性的关键环节&#xff0c;能够最直接地模拟真实驾驶场景&#xff0c;确保…

光伏无人机踏勘,照亮光伏未来!

光伏电站选址地分散在各地&#xff0c;想要精准获取该地的地形特点与屋顶面积等信息&#xff0c;传统的人工踏勘耗时耗力且精度无法保证&#xff0c;难以满足现代光伏项目的规模快发发展需求。光伏无人机踏勘&#xff0c;照亮光伏未来&#xff01; 在光伏无人机智能踏勘设计系统…

uniapp数据缓存

利用uniapp做开发时&#xff0c;缓存数据是及其重要的&#xff0c;下面是同步缓存和异步缓存的使用 同步缓存 在执行同步缓存时会阻塞其他代码的执行 ① uni.setStorageSync(key, data) 设置缓存&#xff0c;如&#xff1a; uni.setStorageSync(name, 张三) ② uni.getSt…

从零开始的c++之旅——多态

1. 多态的概念 通俗来说就是多种形态。 多态分为编译时多态&#xff08;静态多态&#xff09;和运行时多态&#xff08;动态多态&#xff09;。 编译时多态主要就是我们之前提过的函数重载和函数模板&#xff0c;同名提高传不同的参数就可以调 用不同的函数&#xff0c…