当前位置: 首页 > news >正文

数据结构与算法基础(王卓)(16):KMP算法详解(代码实现)

 实现代码的过程中

具体细节、问题:

(1):关于写Get_next函数的标题:


现象:

PPT上写的是:

void get_next(SString T, int &next[])

然而并不能运行,而当我们去掉了引用符号(&)以后:

void get_next(SString T, int next[])

却可以运行,但是这里引用的符号就代表着把数据传回(给)主函数,所以最好不要省略

//&:返回所有我们算出的next[]


原因:

数组不能采用引用格式来传值

根本不存在“元素都是引用的数组”:

本身数组就是用他的首地址来传值的,其首地址代表一大串数组的信息和地址(位置)

而引用传值只是给变量取了一个别名来传值,自然不能无法整个数组的值

总得来说就是一个格式的问题


(2):关于Get_next函数中k的初值:

	int j = 0,//从头开始算起k = -1;next[0] = -1;//根据公式

一开始我们想令 k = 0; ,后面真的想去运行以后发现不可以:

根据公式和算法设计,即使是MAX[k]也必须要小于j


(3):关于KMP函数里,next数组赋初值 和 调用Get_next函数的语句的问题:

不同版本不同教材的不同写法:


 网课(PPT):

	int i = pos, j = 1;

没有给next数组赋初值

也没有调用Get_next函数

啥也没有,主打的就是一个陪伴

这样是肯定不行的:


书上:

	int next[MAXLEN];int i = pos, j = 1;Get_next(T, next);

给next数组赋初值

调用Get_next函数,但是里面写的是next而非next[]

结果:


把书上的改进为:

给next数组赋初值

调用Get_next函数,并且写next[]

	int next[MAXLEN];int i = pos, j = 1;Get_next(T, next[]);

结果也不行:

到这里,我们似乎已经山穷水尽,走投无路了

这个时候多和同学沟通交流就成了关键,于是我们又有了如下进展,这也是我们最终最重要的

问题(3)的收获:


(1):首先:

给next数组赋初值不能少毋庸置疑,没有可能说有那个变量能够不赋初值就直接进行运算操作的

所以PPT上的情况肯定是不行的(差评)


(2):对于书上写的这种情况:

如果我们不要这个Get_next函数的引用符号(不再采用引用传值)

采用实参形参传值,即将其定义的抬头改为:

void Get_next(SString T, int next[])

程序即可成功正确运行:(完整程序如下)这也正是我们

用next最终实现KMP算法的结果:

#include<iostream>
using namespace std;
#include<stdlib.h>//存放exit
#include<math.h>//OVERFLOW,exittypedef int Status;
#define MAXLEN 255struct SString//Sequence String
{char ch[MAXLEN + 1]; //存储串的一维数组int length; //串的当前长度长度
};void Get_next(SString T, int next[])
//给你一个子串T,教你逐个算出每个位序对应的next[]
{int j = 0,//从头开始算起k = -1;next[0] = -1;//根据公式while (j <= T.length - 1)//因为位序从0(而非1)开始{if (k == -1 || T.ch[k] == T.ch[j]){j++;k++;next[j] = k;}elsek = next[k];}
}int Index_KMP(SString S, SString T, int pos)
{int next[MAXLEN];Get_next(T, next);int i = pos, j = 1;while (i <= S.length && j <= T.length){if (S.ch[i] == T.ch[j]){++i; ++j;}//主串和子串依次匹配下一个字符elsej = next[j];}if (j > T.length)return i - T.length; //匹配成功elsereturn 0;
}int main()
{}

同样的,我们不采用引用,我们也还可以采用地址传值,将其定义Get_next的抬头改为:

void Get_next(SString T, int *next)

程序即可成功正确运行:(完整程序如下)

#include<iostream>
using namespace std;
#include<stdlib.h>//存放exit
#include<math.h>//OVERFLOW,exittypedef int Status;
#define MAXLEN 255struct SString//Sequence String
{char ch[MAXLEN + 1]; //存储串的一维数组int length; //串的当前长度长度
};void Get_next(SString T, int *next)
//给你一个子串T,教你逐个算出每个位序对应的next[]
{int j = 0,//从头开始算起k = -1;next[0] = -1;//根据公式while (j <= T.length - 1)//因为位序从0(而非1)开始{if (k == -1 || T.ch[k] == T.ch[j]){j++;k++;next[j] = k;}elsek = next[k];}
}int Index_KMP(SString S, SString T, int pos)
{int next[MAXLEN];Get_next(T, next);int i = pos, j = 1;while (i <= S.length && j <= T.length){if (S.ch[i] == T.ch[j]){++i; ++j;}//主串和子串依次匹配下一个字符elsej = next[j];}if (j > T.length)return i - T.length; //匹配成功elsereturn 0;
}int main()
{}

为什么不能使用引用

其实原因我们可能意想不到,在前面的问题(1)当中其实就已经有能解释该现象原因的解答了:

数组不能采用引用格式来传值

根本不存在“元素都是引用的数组”:

本身数组就是用他的首地址来传值的,其首地址代表一大串数组的信息和地址(位置)

而引用传值只是给变量取了一个别名来传值,自然不能(无法)传递整个数组的值

所以只要我们不用引用传数组,自然不会出问题

然而的虽然得到了标准答案,我们还有新的问题没有解决:


(4):传值问题(小结)

 根据同学提醒,这里其实我们很有必要举一反三,重新温习一下

如果想要通过调用函数功能传达改变的值,除了数组以外的变量,不要用形参实参传值

否则会产生最后数值没变的结果


(5):为什么地址(指针)传值的时候及调用函数的时候不能写next[]

next 既代表整个数组,也代表这个数组的头指针


地址传值:

next 前面已经加了 * 符号,再加 [ ]  就相当于要求接收**next类型的实参数据了,显然不符合我们的出发点


调用函数:

这方面其实我也不是很确定:

显然从设计程序的角度而言,我们清楚地知道这个位置需要的是一个数组的首地址,也就是这个数组的头指针

(我觉得)因为next[]无法代表这个数组的首地址,而直接写数组的名称next肯定是鞥狗代表整个数组(也包括首地址)的

另外,我觉得一定要写出next[]形式的首地址的话,其形式效果相当于:&next[0]


(6):调用Get_next函数是否必要

理论上应该是没有调用数据就传不进去,具体有待验证

(7):else语句当中BF算法的语句是什么?

k--?

待解决


PART 2:关于nextval[ j ]

以后再写,答案:

#include<iostream>
using namespace std;
#include<stdlib.h>//存放exit
#include<math.h>//OVERFLOW,exittypedef int Status;
#define MAXLEN 255struct SString//Sequence String
{char ch[MAXLEN + 1]; //存储串的一维数组int length; //串的当前长度长度
};void Get_nextval(SString T, int nextval[])
//给你一个子串T,教你逐个算出每个位序对应的next[]
{int j = 0,//从头开始算起k = -1;nextval[0] = -1;//根据公式while (j <= T.length){if (k == -1 || T.ch[k] == T.ch[j]){j++;k++;if (T.ch[k] != T.ch[j])nextval[j] = k;elsenextval[j] = nextval[k];}elsek = nextval[k];}
}int Index_KMP(SString S, SString T, int pos)
{int nextval[MAXLEN];Get_nextval(T, nextval);int i = pos, j = 1;while (i <= S.length && j <= T.length){if (S.ch[i] == T.ch[j]){++i; ++j;}//主串和子串依次匹配下一个字符elsej = nextval[j];}if (j > T.length)return i - T.length; //匹配成功elsereturn false;
}int main()
{} 

相关文章:

数据结构与算法基础(王卓)(16):KMP算法详解(代码实现)

实现代码的过程中 具体细节、问题&#xff1a; &#xff08;1&#xff09;&#xff1a;关于写Get_next函数的标题&#xff1a; 现象&#xff1a; PPT上写的是&#xff1a; void get_next(SString T, int &next[]) 然而并不能运行&#xff0c;而当我们去掉了引用符号&…...

九龙证券|盘前直接腰斩,银行巨头紧急“拔网线”!美股银行股又崩了?

见证历史了&#xff0c;又有一家银行巨子倒下&#xff1f; 美股银行股团体暴降 上一交易日暴降超60%的硅谷银行持续面对腥风血雨。盘前&#xff0c;硅谷银行跌幅超50%&#xff0c;随后&#xff0c;公司宣布盘前暂停交易&#xff0c;等待刊发消息。 而最新消息显现&#xff0c…...

接口优化常用思路

空间换时间 计算机程序中最大的矛盾是空间和时间的矛盾&#xff0c;那么&#xff0c;从这个角度出发逆向思维来考虑程序的效率问题&#xff0c;我们就有了解决问题的第1招–以空间换时间 合理使用缓存就是一个很好的例子&#xff0c;针对一些频繁使用且不频繁变更的数据&#…...

【SpringCloud】SpringCloud面试题整理

文章目录1、什么是Spring Cloud&#xff1f;2、Spring Cloud和Dubbo的区别3、REST和RPC的区别4、SpringCloud如何实现服务的注册和发现5、什么是服务熔断和服务降级&#xff1f;6、项目中zuul常用的功能7、服务网关的作用8、ribbon和feign区别9、ribbon的负载均衡策略10、简述什…...

一些数据库知识点总结

DB2数据库&#xff1a;从数据库表中第I条记录开始检索J条记录SELECT * FROM (SELECT A.*, ROW_NUMBER() OVER() AS NFROM (SELECT * FROM table_name) AS A)WHERE N > I AND N < J;Oracle数据库&#xff1a;从数据库表中第M条记录开始检索N条记录SELECT * FROM (SELECT R…...

Python unittest 模块

一、Unittest 的几个基本概念 TestCase &#xff1a;要写的具体的测试用例TestSuite&#xff1a; 多个测试用例集合&#xff08;或测试套件/测试集&#xff09;TestLoader&#xff1a;用来加载 TestCase 到 TestSuite中的&#xff08;更通俗一点&#xff0c;就是用来把符合我们…...

Spring - Spring IoC 容器相关面试题总结

文章目录01. Spring IoC 和依赖注入是什么&#xff1f;02. Spring IoC 的优点和缺点分别是什么&#xff1f;03. Spring IoC 有什么作用和功能&#xff1f;04. Spring 依赖注入的方式&#xff1f;05. Spring 构造器注入和 setter 方法注入的区别&#xff1f;06. Spring 依赖注入…...

顺序表来喏!!!

前言&#xff1a;还记得前面的文章&#xff1a;《通讯录的实现》吗&#xff1f;通讯录的完成就借助了顺序表这种数据结构&#xff01;&#xff01;&#xff01;那么今天我们就来介绍我们的顺序表介绍顺序表前&#xff0c;我们来了解一下线性表的概念线性表&#xff1a;线性表&a…...

【H2实践】之 SpringBoot 与 H2 数据交互

一、目标 本文是【H2实践】之认识 H2&#xff0c;【H2实践】之 SpringBoot 整合的后续。前文分别介绍了 H2 及其简单使用&#xff0c;并完成了 H2 与 SpringBoot 的整合。本文将紧接 【H2实践】之 SpringBoot 整合 探索实用 SpringBoot 结合 JPA 通过 web 接口操作 H2 数据库的…...

LeetCode 424. Longest Repeating Character Replacement

LeetCode 424. Longest Repeating Character Replacement https://leetcode.com/problems/longest-repeating-character-replacement/ 题目描述 You are given a string s and an integer k. You can choose any character of the string and change it to any other upperc…...

建立自己的博客(记录-不推荐)

环境安装&#xff1a; w10系统安装 第一步&#xff1a;安装git Git 官网: https://git-scm.com/ 第二步&#xff1a;安装Node.js Node.js官网&#xff1a;https://nodejs.org/zh-cn/ 使用cmd检测&#xff1a; node -v 第三步&#xff1a;安装Hexo Hexo官网&#xff1a;htt…...

hashmap存储方式 hash碰撞及其解决方式

1.Map的存储特点 在Map这个结构中&#xff0c;数据是以键值对&#xff08;key-value&#xff09;的形式进行存储的&#xff0c;每一个存储进map的数据都是一一对应的。 创建一个Map结构可以使用new HashMap()以及new TreeMap()两种方式&#xff0c;两者之间的区别是&#xff1a…...

Amazon GuardDuty 的新增功能 – Amazon EBS 卷的恶意软件检测

亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者对接世界最前沿技术&#xff0c;观点&#xff0c;和项目&#xff0c;并将中国优秀开发者或技术推荐给全球云社区。如果你还没有关注/收藏…...

YOLOv7 pytorch

yolov7主干部分结构图&#xff1a;yolov7主干 yolov7数据集处理代码&#xff1a;yolov7数据集处理代码 yolov7训练参数解释&#xff1a;yolov7训练参数【与本文代码有区别】 yolov7训练代码详解&#xff1a;yolov7训练代码详解 目录 训练自己的训练集 训练自己的训练集 此…...

JDK自带JVM分析工具

一、JDK自带工具盘点&#xff1a; jstat&#xff1a;性能分析-查看gc情况&#xff1b; jmap&#xff1a;内存分析-堆信息&#xff1b; jstack&#xff1a;线程分析-栈信息&#xff1b; jinfo&#xff1a;参数查看及配置&#xff1b; jstatd&#xff1a;启动jvm监控服务。它…...

IO多路复用--[select | poll | epoll | Reactor]

因为在简历上写了netty的项目&#xff0c;因此还是将网络底层的那点东西搞清楚。 首先希望明确的是&#xff0c;BIO、NIO、IO多路复用这是不同的东西&#xff0c; 我会在本文中详细讲出来。 本文参考资料&#xff1a; JAVA IO模型 IO多路复用 select poll epoll介绍 从BIO到epo…...

pod的requests、limits解读、LimitRange资源配额、Qos服务质量等级、资源配额管理 Resource Quotas

前言 环境&#xff1a;k8s-v1.22.17 docker-20.10.9 centos-7.9 目录前言什么是可计算资源CPU、Memory计量单位pod资源请求、限额方式pod定义requests、limits查看节点资源情况pod使用request、limits示例LimitRange限制命名空间下的pod的资源配额Qos服务质量等级资源配额管理…...

R语言基础(六):函数

R语言基础(一)&#xff1a;注释、变量 R语言基础(二)&#xff1a;常用函数 R语言基础(三)&#xff1a;运算 R语言基础(四)&#xff1a;数据类型 R语言基础(五)&#xff1a;流程控制语句 7. 函数 函数是一组完成特定功能的语句。 7.1 内置函数 R语言系统中提供许多内置函数&…...

[C++] 简单序列化

前言 序列化(Serialization) 是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间&#xff0c;对象将其当前状态写入到临时或持久性存储区。以后&#xff0c;可以通过从存储区中读取或反序列化对象的状态&#xff0c;重新创建该对象。 使用 序列化 std::array&…...

Autosar Configuration(十三)SomeIP之配置TCP/IP

本系列教程是根据实际项目开发中总结的经验所得,如发现有不对的地方,还请指正。 目录Autosar Configuration(一)Davinci Developer-工具介绍 Autosar Configuration(二)Davinci Developer-SWC配置 Autosar Configuration(三) Security之Crypto配置 Autosar Configurat…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...

【51单片机】4. 模块化编程与LCD1602Debug

1. 什么是模块化编程 传统编程会将所有函数放在main.c中&#xff0c;如果使用的模块多&#xff0c;一个文件内会有很多代码&#xff0c;不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里&#xff0c;在.h文件里提供外部可调用函数声明&#xff0c;其他.c文…...

SpringCloud优势

目录 完善的微服务支持 高可用性和容错性 灵活的配置管理 强大的服务网关 分布式追踪能力 丰富的社区生态 易于与其他技术栈集成 完善的微服务支持 Spring Cloud 提供了一整套工具和组件来支持微服务架构的开发,包括服务注册与发现、负载均衡、断路器、配置管理等功能…...

JS的传统写法 vs 简写形式

一、条件判断与逻辑操作 三元运算符简化条件判断 // 传统写法 let result; if (someCondition) {result yes; } else {result no; }// 简写方式 const result someCondition ? yes : no;短路求值 // 传统写法 if (condition) {doSomething(); }// 简写方式 condition &…...

浏览器工作原理01 [#]Chrome架构:仅仅打开了1个页面,为什么有4个进程

引用 浏览器工作原理与实践 Chrome打开一个页面需要启动多少进程&#xff1f;你可以点击Chrome浏览器右上角的“选项”菜单&#xff0c;选择“更多工具”子菜单&#xff0c;点击“任务管理器”&#xff0c;这将打开Chrome的任务管理器的窗口&#xff0c;如下图 和Windows任务管…...

成工fpga(知识星球号)——精品来袭

&#xff08;如需要相关的工程文件请关注知识星球&#xff1a;成工fpga&#xff0c;https://t.zsxq.com/DMeqH&#xff0c;关注即送200GB学习资料&#xff0c;链接已置顶&#xff01;&#xff09; 《孩子都能学会的FPGA》系列是成工完成的第一个系列&#xff0c;也有一年多的时…...