串的匹配算法——KMP算法

news2024/11/26 12:24:48

目录

一.特点

二.算法思想

三.公式证明

四.next数组及其练习

 五.找规律计算next[k]

六.代码实现


一.特点

BF算法的特点是i回退,KMP算法的最大特点是i不回退,由于i不回退,所以KMP算法的时间复杂度是O(n+m)。

二.算法思想

在匹配主串和子串时,i指向主串,j指向子串,字符相等则i,j同时加1,当字符失配时,i不回退,j退到k的位置(相当必然有一段相同的路,那么相同的路i不走,等着j走过来即可)即相等的路j走过一段k长度的路。

三.公式证明

结论:

 在匹配成功的子串中找到两个最长的相等的真子串,这两个子串满足如下特点:

  1. 一个串以子串的开头作为开头。
  2. 另一个串以失配前的最后一个字符作为结尾(p_{j-1})。
  3. k正是子串的长度。

四.next数组及其练习

我们把所有位置的k值给保存在数组中,这个数组就是next数组。

1.

2.

 3.

4.

 五.找规律计算next[k]

例子:“abcabcdabcdabcdeabc”

不妨假设next[j]=k;

已知:next[1]=0,next[0]=-1;

由next[j]=k,得到p_{0}...p_{k-1}=p_{j-k}...p_{j-1}  (1)

如果p_{k}=p_{j}   (2)

(1)+(2)=p_{0}...p_{k}=p_{j-k}...p_{j}

得到next[j+1]=k+1;

如图k=3

如果p_{k}!=p_{j}

又变成了一个模式匹配的问题,那么k=next[k];如图k=next[3]=0;

KMP最大特点是指示主串的指针不需要回溯,整个匹配过程中,对主串仅需从头到尾扫描一遍,这对处理从外设输入的庞大文件很有效,可以边读入边匹配,而无需回头重读。

六.代码实现

static int* GetNext(const char* str)
{
	int len = strlen(str);
	int* next = (int*)malloc(sizeof(int) * len);
	next[0] = -1;//不能再退
	next[1] = 0;//j=1,k=0;

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

int KMP(const char* str, const char* sub, int pos)
{
	assert(str != NULL && sub != NULL);
	if (str == NULL || sub == NULL || pos<0 || pos>strlen(str))
		return -1;

	int i = pos;
	int j = 0;
	int lenstr = strlen(str);
	int lensub = strlen(sub);
	int* next=GetNext(sub);
	//while (str[i] != '\0' && sub[j] != '\0')
	while (i < lenstr && j < lensub)
	{
		if ((j==-1)||str[i] == sub[j])
		{
			i++;
			j++;
		}
		else
		{
			//i不回退
			j = next[j];
		}
	}
	free(next);
	//判断是否查找成功,利用子串是否遍历完成,来判断是否查找成功
	//if (sub[j] == '\0')
	if (j >= lensub)
		return i - j;
	else
		return -1;
}

int main()
{
	const char* str1 = "ababcabcdabcde";
	const char* str2 = "abcd";

	printf("%d\n", KMP(str1, str2, 0));
	printf("%d\n", KMP(str1, str2, 6));
	printf("%d\n", KMP(str1, str2, 10));

	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu 22.04修改静态ip

1. 备份原网络配置文件 # 配置文件名称因机器设置有异 cd /etc/netplan cp 01-network-config.yaml 01-network-config.yaml.bak# 文件内容如下 network:version: 2renderer: NetworkManager2. 修改配置文件 使用 ipconfig 命令查看网络信息&#xff0c;ip addr 命令也可 我这…

day52(vueJS)json-server模拟数据

json-server介绍&#xff1a;&#xff1a;&#xff1a;JSON Server 是一个用于快速搭建 REST API 的工具&#xff0c;它可以帮助我们在开发过程中快速模拟 一个后端 API 服务器&#xff0c;方便前端开发人员进行接口调试和开发。使用 JSON Server&#xff0c;你可以通过创建一个…

【Vue】VueX仓库

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;Vue ⛺️稳中求进&#xff0c;晒太阳 目录 Vue概述 是什么 场景&#xff1a; 优势 构建多组件共享环境 创建一个空仓库 核心概念 - state 状态 1. 提供数据 2.使用数据 ​编辑 …

在虚拟机vm下的Linux系统下 安装redis 超详细

打开Linux后 右键打开终端 1.输入:su root 登录root 密码是123456 2.然后输入:yum -y install gcc-c 安装gcc基础依赖包 3.yum -y install centos-release-scl 4.yum -y install devtoolset-9-gcc devtoolset-9-gcc-c devtoolset-9-binutils //为了编译最新版本的Redis源码 用…

纯手工搭建一个springboot maven项目

前言&#xff1a;idea社区版无法自动搭建项目&#xff0c;手动搭建的经验分析如下&#xff1a; 1 包结构 参考下图&#xff1a; 2 项目结构 3 maven依赖 具体的项目如图&#xff1a; 依据这个结构配置一个springboot 的 pom依赖&#xff1a; <?xml version"1.0…

SanctuaryAI推出Phoenix: 专为工作而设计的人形通用机器人

文章目录 1. Company2. Main2.1 关于凤凰™ (Phoenix)2.2 关于碳™(Carbon)2.3 商业化部署2.4 关于 Sanctuary Corporation 3. My thoughtsReference彩蛋&#xff1a;将手机变为桌面小机器人 唯一入选《时代》杂志 2023 年最佳发明的通用机器人。 称机器人自主做家务的速度和灵…

js SheetJS 合并表格导出到同一个excel中

最近有个需求,我在一个页面显示了4个表格, 然后合并导出到excel文件中 四个表,四个sheet,一个excel文件 最后导出时这样: 实现: 1,页面有个导出的checkbox,勾选则导出,不勾选不处理 2,在一个函数中,集中处理四个表数据获取,并将结果返回出来 //获取数据后返回为…

【C++】递归 1241 - 角谷猜想 1108 - 正整数N转换成一个二进制数

文章目录 一、问题&#xff1a;1241 - 角谷猜想二、问题&#xff1a;1108 - 正整数N转换成一个二进制数三、总结四、感谢 一、问题&#xff1a;1241 - 角谷猜想 类型&#xff1a;有规律的循环、递归。 题目描述&#xff1a; 日本一位中学生发现一个奇妙的定理&#xff0c;请角…

如何判断可编程电子负载是否合格?

可编程电子负载是一种可以模拟实际负载的电子设备&#xff0c;广泛应用于电源、电池、充电器等产品的测试和研发。判断可编程电子负载是否合格&#xff0c;需要从以下几个方面进行考量&#xff1a; 精度是衡量电子负载性能的重要指标&#xff0c;包括电流精度、电压精度、功率精…

ImportError: Could not import docarray python package解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

Qt 使用QListView实现简约美观的聊天窗口

今天和大家分享一个使用QListView来展现聊天窗口的历史记录的例子, 因为聊天记录可能会有很多, 所以使用试图-模型的方式更加合理 这是最终效果: ChatHistoryModel继承自QAbstractListModel , ChatHistoryViewDelegate继承自QStyledItemDelegate, 这个例子最关键的就是在QSty…

Keil MDK安装armcc V5编译器

不知道从什么时候开始&#xff0c;Keil MDK默认不支持V5的编译器了&#xff0c;里面默认只有V6的编译器&#xff0c;设置界面跟V5有很大的差异不太熟悉。最可怕的是&#xff0c;之前使用V5编译的工程&#xff0c;换成V6编译器后居然报错...虽然修改一下应该也可以正常编译&…

几种常用的查看Ros话题的命令

1、查看 rqt_tf_tree rosrun rqt_tf_tree rqt_tf_tree 2、查看ros node 关系 rqt_graph 3、列出所有话题 rostopic list 4、查看某一话题的类型 以 /scan 为例 rostopic type /scan 5、查看某个数据类型包含哪些数据 rosmsg show sensor_msgs/LaserScan sensor_…

Gitlab修改仓库权限为public、Internal、Private

Public&#xff08;公开&#xff09;&#xff1a;所有人都可以访问该仓库&#xff1b; Internal&#xff08;内部&#xff09;&#xff1a;同一个GitLab群组或实例内的所有用户都可以访问该仓库&#xff1b; Private&#xff08;私人&#xff09;&#xff1a;仅包括指定成员的用…

2024年最新《国际预警期刊》正式更新!

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、国际期刊预警名单的变化&#xff1f;二、课程案例展示&#xff08;篇幅有限仅展示部分&#xff09;1.【热图系列】2.【九象限图系列】3.【富集分析系列】4.【机…

自动化测试基础——Pytest框架之YAML详解以及Parametrize数据驱动

文章目录 一、YAML详解1.YAML作用2.YAML语法结构3.YAML数据类型3.1.对象3.2.数组3.3.标量 4.YAML的引用5.YAML类型转换 二、YAML的读写与清空1.YAML的读2.YAML的写3.YAML的清空 三、pytest的parametrize简单数据驱动四、pytest的parametrize结合yaml实现数据驱动五、解决pytest…

数据库期末速成100分训练,附练手数据库原件及教程

本文提供下面数据库代码的数据库原件&#xff0c;下载后可使用 教程如下&#xff1a; 1.打开sql sever 2.找到数据库 3.右键数据库点击“附加”&#xff0c;然后点击“添加” 4.导入数据库原件&#xff0c;点击确定 ps&#xff1a;如果没有sqlsever 或者页面编辑器&#x…

基于SSM的农业信息管理系统的设计与实现(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的农业信息管理系统的设计与实现&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;…

JavaScript中的innerHTML、value属性,零基础开发web前端

CSS篇 让一个元素水平垂直居中&#xff0c;到底有多少种方案&#xff1f;浮动布局的优点&#xff0c;缺点&#xff1f;清除浮动的方式&#xff1f;使用display:inline-block会产生的问题&#xff1f;解决方法&#xff1f;布局题&#xff1a;div垂直居中&#xff0c;左右10px&a…

LeNet5实战——衣服分类

搭建模型训练代码&#xff08;数据处理、模型训练、性能指标&#xff09;——> 产生权重w ——>模型结构c、w测试 配置环境 Pycharm刚配置的环境找不到了-CSDN博客 model.py 导入库 import torch from torch import nn from torchsummary import summary 模型搭…