北邮22信通:(13)第三章 3.4 串的实现 KMP算法

news2024/11/20 15:20:13

北邮22信通一枚~   

跟随课程进度每周更新数据结构与算法的代码和文章 

持续关注作者  解锁更多邮苑信通专属代码~

上一篇文章:

下一篇文章:

***说明***

1.本代码结合书上第二章线性表和4.3.3KMP算法结合书写。

2.加快匹配速度的根本原因:前缀子串无需匹配

3.关于申请堆区动态数组的缓冲区问题:

        每次申请堆空间时,系统会自动利用已经申请单还未利用的堆空间作为数据缓冲区,通俗的讲,就是系统要给你将要输入的数据提前预测一下区域,看看你再输入数据之后会不会导致数据溢出。

        程序很害怕这种事情发生,所以总是很小心翼翼的留出一个数据缓冲区,每次你输入完数据,数据都会进入上一次输入数据时产生的缓冲区中,然后缓冲区后移;直到缓冲区到了申请的堆空间最低端,程序就会发出警告,如果你再不考虑多申请一点堆空间的话,数据就要溢出啦!!!然后就会在语句底下给你画小绿线……所以!!!适当多申请点儿空间!!!

4.KMP函数中的实现过程和BF算法类似,明白了BF自然就轻轻松松明白KMP,所以重点是前面写的getnextarray函数。

***说明完毕***

一.顺序表实现KMP算法

KMP算法部分:

template<class temp>
void seqlist<temp>::getnextarray(seqlist<temp>& t, int*& next)
{
	next = new int[t.getlength() + 10];
	/*如果写成next = new int[t.getlength() + 1]会有建议提示:
	“写入next时缓存区溢出”,原因如下:
	next动态数组缓冲区溢出动态数组基本全部被占满,数据缓冲区不够;
	所以应多给动态数组分配一点存储空间以增加缓存区容量*/
	next[1] = 0;
	next[2] = 1;
	int p = 1;
	for (int j = 3; j <= t.getlength(); ++j)
	{
		while (p > 1 && t.get(p) != t.get(j - 1))
			p = next[p];
		if (t.get(p) == t.get(j - 1))
			++p;
		next[j] = p;
	}
}

template<class temp>
int seqlist<temp>::KMP(seqlist<temp>& t)
{
	int* next;
	getnextarray(t, next);
	int i = 1, j = 1;
	while (i <= this->getlength() && j <= t.getlength())
	{
		if (get(i) == t.get(j))
		{
			i++; j++;
		}
		else if (!next[j])
		{
			i++; j = 1;
		}
		else
			j = next[j];
	}
	delete[]next;
	if (j > t.getlength())return i + 1 - j;
	else return -1;
}

代码部分及运行结果:

#include <iostream>
using namespace std;
#define N 100
template<class temp>
class seqlist
{
private:
	temp data[N];
	int length;
public:
	seqlist() { length = 0; }
	seqlist(temp a[], int n);
	int getlength() { return length; }
	void printlist();
	void insert(int i, temp x);
	temp del(int i);
	temp get(int i);
	int locate(temp x);
	void getnextarray(seqlist<temp>& t, int*& next);
	int KMP(seqlist<temp>& t);
};

template <class temp>
seqlist<temp>::seqlist(temp a[], int n)
{
	if (n > N)throw "数组长度超过顺序表最大长度";
	for (int i = 0; i < n; i++)
		this->data[i] = a[i];
	this->length = n;
}

template<class temp>
void seqlist<temp>::printlist()
{
	cout << "按序号依次遍历线性表中各个数据元素:" << endl;
	for (int i = 0; i < this->length; i++)
		this->data[i].print();
	cout << endl;
}

template<class temp>
void seqlist<temp>::insert(int i, temp x)
{
	if (this->length >= N)throw"上溢异常";
	if (i < 1 || i >= this->length + 1)throw"位置异常";
	for (int j = this->length; j >= i; j--)
		this->data[j] = this->data[j - 1];
	this->data[i - 1] = x;
	this->length++;
}

template<class temp>
temp seqlist<temp>::del(int i)
{
	if (this->length == 0)throw"下溢异常";
	if (i<1 || i>this->length)throw"位置异常";
	temp x = data[i - 1];
	for (int j = i; j < this->length; j++)
		data[j - 1] = data[j];
	this->length--;
	return x;
}


template<class temp>
temp seqlist<temp>::get(int i)
{
	if (i<1 || i>this->length)throw"查找位置非法";
	return this->data[i - 1];
}

template<class temp>
int seqlist<temp>::locate(temp x)
{
	for (int i = 0; i < this->length; i++)
		if (this->data[i] == x)return(i + 1);
	return 0;
}

template<class temp>
void seqlist<temp>::getnextarray(seqlist<temp>& t, int*& next)
{
	next = new int[t.getlength() + 10];
	/*如果写成next = new int[t.getlength() + 1]会有建议提示:
	“写入next时缓存区溢出”,原因如下:
	next动态数组缓冲区溢出动态数组基本全部被占满,数据缓冲区不够;
	所以应多给动态数组分配一点存储空间以增加缓存区容量*/
	next[1] = 0;
	next[2] = 1;
	int p = 1;
	for (int j = 3; j <= t.getlength(); ++j)
	{
		while (p > 1 && t.get(p) != t.get(j - 1))
			p = next[p];
		if (t.get(p) == t.get(j - 1))
			++p;
		next[j] = p;
	}
}

template<class temp>
int seqlist<temp>::KMP(seqlist<temp>& t)
{
	int* next;
	getnextarray(t, next);
	int i = 1, j = 1;
	while (i <= this->getlength() && j <= t.getlength())
	{
		if (get(i) == t.get(j))
		{
			i++; j++;
		}
		else if (!next[j])
		{
			i++; j = 1;
		}
		else
			j = next[j];
	}
	delete[]next;
	if (j > t.getlength())return i + 1 - j;
	else return -1;
}

int main()
{
	system("color 0A");
	char a[] = "hello world";
	char b[] = "good";
	char c[] = "ello";
	seqlist<char>seqa(a, strlen(a));
	seqlist<char>seqb(b, strlen(b));
	seqlist<char>seqc(c, strlen(c));
	cout << seqa.KMP(seqa) << endl;//1
	cout << seqa.KMP(seqb) << endl;//-1
	cout << seqa.KMP(seqc) << endl;//2
	return 0;
} 

“诶博主 你是不是少了一个主标题和内容啊”

“没有没有没有!”(理直气壮)(逃跑)

等我醒了再更…… 

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

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

相关文章

行业分析| 新的学习方式——在线自习室

互联网技术在快速革新中不断推动新应用、新场景、新模式和新业态的发展融通&#xff0c;如近年来不断催生的游戏直播、直播带货、户外直播等网络生态。随着互联网用户逐年增多&#xff0c;年轻化趋势明显&#xff0c;互联网直播内容逐渐向生活化、日常化拓展&#xff0c;加之“…

Linux 防火墙常用命令

目录 前文叙述 Linux 找不到 firewall 命令 firewalld 常用管理命令 firewall-cmd 常用命令参数说明 前文叙述 Linux 防火墙默认为开启状态&#xff0c;生产环境下 Linux 防火墙也肯定是开启状态。因此在生产环境下往往是开放特定端口让外部进行连接使用。 Linux 找不到 fir…

数字化时代,企业为什么越来越重视数据分析

自数据成为第五大生产要素后&#xff0c;其价值得到了越来越多企业的认可&#xff0c;也成为了各行各业企业的重要的资产。而信息化建设在企业中的发展更是给了数据增长的机会&#xff0c;随着业务信息系统在企业中成为基础建设&#xff0c;众多企业都通过业务系统沉淀了大量业…

JSP的基本使用总结

JSP的基本使用总结 &#x1f3e0;个人主页&#xff1a;shark-Gao &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是shark-Gao&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f389;目前状况&#xff1a;23届毕业生&#xff0c;目前在…

海睿思分享 | 风控监管,守住企业生命线

1 企业如何应对市场风险 随着市场形势日益严峻&#xff0c;企业风险系数也在同步增加&#xff0c;一旦风险管理出现重大问题&#xff0c;将是致命的、灾难性的&#xff0c;可能导致企业出现生存危机。 风控监管的主要目的在于通过对各类风险进行识别、分析、监控&#xff0c…

【java web篇】MyBatis之Mapper代理

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

MacOS版本RedisDesktopManager源码编译

1. 克隆 : git clone --recursive https://github.com/RedisInsight/RedisDesktopManager.git 查看依赖模块: git submodule 编译注意事件,部分源码的子仓库依赖没有下载完整的,要手动下载 brotli子模块 编译brotli子模块 $ mkdir out && cd out $ ../configure-c…

助力春耕:数智驱动现代农业高质量发展

最近有部很有意思的综艺《种地吧&#xff01;少年》&#xff0c;节目内容就是十个少年要用192天的时间在142亩土地上&#xff0c;完成抢收水稻&#xff0c;抢种小麦&#xff0c;并在6月份完成小麦的收割&#xff0c;这样一个内容。 这个节目没有流量明星&#xff0c;而被吸引去…

MyBatis(十六)MyBatis使用PageHelper

一、limit分页 mysql的limit后面两个数字&#xff1a; 第一个数字&#xff1a;startIndex&#xff08;起始下标。下标从0开始。&#xff09; 第二个数字&#xff1a;pageSize&#xff08;每页显示的记录条数&#xff09; 假设已知页码pageNum&#xff0c;还有每页显示的记录…

K8s集群搭建-Kubeadm方式搭建集群【1.23.0版本】

文章目录 一、初始化准备二、安装kubeadm三、初始化Master集群四、将新的Node节点加入集群五、部署CNI网络插件六、其他配置 Kubernetes1.24(包括1.24)之后不在兼容docker,如果有需要兼容docker的需求&#xff0c;则安装一个 cri-docker的插件&#xff0c;本文使用的是kuberne…

【技巧】如何在微信与企业微信端实现自动化ChatGPT智能机器人服务?(WorkTool)

场景描述 对于使用企业微信办公协作的公司/团体/组织等&#xff0c;在工作的时候&#xff0c;经常需要通过群机器人的方式&#xff0c;回答群内成员的问题。 基于此&#xff0c;一些企业想要将ChatGPT的智能对话能力与企业微信群机器人的回复能力结合&#xff0c;在企业微信群…

VMware Site Recovery Manager 8.7 (for vSphere 8 U1) - 数据中心灾难恢复 (DR)

请访问原文链接&#xff1a;https://sysin.org/blog/vmware-srm-8/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Site Recovery Manager 8.7 | 18 APR 2023 | Build 21590800 什么是 Site Recovery Manager (SRM)&#xff1…

【网络安全】CVE漏洞分析以及复现

漏洞详情 Shiro 在路径控制的时候&#xff0c;未能对传入的 url 编码进行 decode 解码&#xff0c;导致攻击者可以绕过过滤器&#xff0c;访问被过滤的路径。 漏洞影响版本 Shiro 1.0.0-incubating 对应 Maven Repo 里面也有 【一一帮助安全学习&#xff0c;所有资源获取一…

GrapeCity Documents for Imaging

GrapeCity Documents for Imaging 现在可以使用高斯模糊效果在整个输入图像或部分图像上基于高斯函数创建模糊。 在GcBitmap类中添加了IsBlackAndWhite和IsGrayscale。这些方法可以更快地检查图像是由黑白像素组成还是仅由灰度组成。 IsBlackAndWhite方法检查所有图像像素是不透…

回炉重造八--系统启动和内核管理

系统启动和内核管理 1、系统启动 1.1 centos7启动的过程 UEFI或BIOS初始化&#xff0c;运行post开机自检选择启动的设备&#xff08;USB、硬盘、本地光盘&#xff09;引导装载程序&#xff0c;centos7是给grub2加载装载程序的配置文件&#xff1a; /etc/grub.d/ /etc/default…

使用 Amazon Step Functions 和 Amazon Athena 实现简易大数据编排

很多公司都在亚马逊云上围绕 Amazon S3 实现了自己的数据湖。数据湖的建设涉及到数据摄入、清洗、转换&#xff0c;以及呈现等多个步骤&#xff0c;还需要对这些步骤进行编排&#xff0c;这对很多人手不足或者初识数据湖的团队形成了挑战。 在本篇文章中&#xff0c;我将介绍一…

可以一口气读完的算法书

算法&#xff01;Algorithms&#xff01; 咳咳&#xff01;很多人一听到这个词&#xff0c;估计脑袋就要炸了&#xff1a;一定又是复杂极了的东西&#xff0c;看来此书必定翻不过第一节&#xff0c;就要睡着了。 没错&#xff0c;很多算法书虽然写得很精妙&#xff0c;但凭我…

【OpenLayers】VUE+OpenLayers+ElementUI加载WMS地图服务

【OpenLayers】VUEOpenLayersElementUI加载WMS地图服务 准备工作安装vue创建vue项目安装OpenLayers安装ElementUI加载wms地图服务 准备工作 需要安装好nodejs&#xff0c;nodejs下载地址&#xff0c;下载对应的版本向导式安装即可。 安装完成后&#xff0c;控制台输入node -v…

OAID解密场景和对应策略,淘宝订单解密接口,淘宝订单明文接口

OAID解密场景和对应策略 场景编码 场景名称 返回的隐私字段 1001 顺丰电子面单发货 消费者手机号&#xff0c;姓名&#xff0c;详细地址 1002 4通一达电子面单发货 消费者手机号&#xff0c;姓名&#xff0c;详细地址 1003 EMS电子面单发货 消费者手机号&#xff0c…

Eclipse基本使用、数据类型、运算符

Eclipse基本使用 创建JAVA项目 1.打开新建项目窗口&#xff08;File --> New --> Project&#xff09; 2.在New Project窗口中选择Java Project创建项目 3.在New Java Project对话框 Project name&#xff1a;项目名称 Project Layout项目布局&#xff1a;Create sepa…