【数据结构】四、串

目录

一、定义

二、表示与实现

定长顺序存储

堆分配存储

链式存储

三、BF算法

四、KMP算法

1.求next数组

方法一

方法二(考试方法)

2.KMP算法实现

方法一

方法二

3.nextval

4.时间复杂度 


本节最重要的就是KMP算法,其他要求不高

一、定义

串类型的定义:串即字符串,是由零个或多个字符组成的有限序列,是数据元素为单个字符的特殊线性表。

串长:串中字符的个数(n≥0),n=0 时称为空串\O \varnothing

空白串:由一个或多个空格符组成的串,空串不等于空白串

子串:串S中任意个连续的字符序列叫S的子串, S叫主串(空串是任意串的子串;任意串S都是S本身的子串,除S本身外,S的其他子串称为S的真子串)

子串位置:子串的第一个字符在主串中的序号

字符位置:字符在串中的序号

串相等:串长度相等,且对应位置上字符相等

下面关于串的的叙述中,哪一个是不正确的?

A. 串是字符的有限序列

B. 空串是由空格构成的串

C. 模式匹配是串的一种重要运算

D. 串既可以采用顺序存储,也可以采用链式存储

答案:B 

二、表示与实现

定长顺序存储

用预先设定好长度的数组存储串。string[MAXSIZE + 1],加一是为了给串尾的‘\0’留空间

堆分配存储

也就是用malloc动态创建数组,还可以用realloc增加空间

链式存储

用链表存储串值,易插入和删除

1.链表结点的数据域长度取1

2.链表结点数据域长度取n(块链结构)

当数据元素较多时,块链结构存储密度更高

三、BF算法

BF算法是一种串的模式匹配算法,目的是确定主串中所含子串第一次出现的位置

思路

主串S,模式串T

将ST的头部对齐,逐个比较字符是否相同

一旦出现不同,将T后移一位,重新从头开始比较

直到完全匹配为止,否则匹配失败

写成代码:

主串S,模式串T【i,j为S,T的指针】

将ST的头部对齐【i,j分别指向S,J的首位】,逐个比较字符是否相同【S[i]==T[j]】

一旦出现不同【S[i] != T[j]】,将T后移一位【i = i - j + 2(回溯)】,重新从头开始比较【j指向T首位】

直到完全匹配为止【j > T的长度】,否则匹配失败【i > S的长度】

时间复杂度:最坏情况为:主串n长,子串m长;除了最后一次,每一次都比较到子串最后一位发现不匹配,总共比较 m*(n-m+1)+m 次。时间复杂度 O(n*m)

四、KMP算法

改进BF算法:当字符不匹配时,利用已匹配部分的信息,仅让模式串回溯,主串不回溯

模式串要回溯到什么地方呢?目标地点记录在next[ ]数组中

next数组是干什么的呢?next数组记录了已匹配部分最大相同前后缀的信息

比如

S = a b a c c a b a b

P = a b a b

开始匹配

S = a b a c c a b a b

P = a b a

前三位都匹配,第四位b与c不匹配

此时我们知道已匹配的部分为a b a,它有相同的前后缀‘a

我们只需要让T的“前缀”与S的“后缀”对齐,接着比较即可。主串不需要回溯,子串也不用从头开始

S = a b a c c a b a b

P =       a b a b

next数组是一个与模式串等长的数组,它告诉我们,模式串第几位失配时我们要跳转到哪里

所以关键在于求next数组

1.求next数组

方法一

计算next数组流程图

方法二(考试方法)

假设next从j = 1开始编号

1)j = 1时,next[j] = 0

2)j > 1时,next[j] = j之前的最大相同前后缀长度 +1

3)j > 1时,找不到相同前后缀时,next[j] = 1

比如

方法二可以由方法一每位都加一得到,哪个舒服用哪个

2.KMP算法实现

方法一

完整例子,找到一段话中的所有匹配:

// 在一篇英文文章中查找指定的模式串,采用KMP算法实现#include<stdio.h>
#include<stdlib.h>
#include<string.h>#define elemtype charelemtype* getnext(elemtype* p)  //传入模式串得到next数组
{ int pnum = strlen(p);elemtype* next = (elemtype*)malloc(sizeof(elemtype) * pnum);next[0] = 0;int len = 0;int k = 1;//生成next数组while (p[k] != '\0') {if (p[len] == p[k])next[k++] = ++len;else(len == 0 ? next[k++] = 0 : len = next[len - 1]);}//调整next数组for (k = pnum - 2; k >= 0; k--)   next[k + 1] = next[k];next[0] = -1;//输出next数组printf("next数组为:");for (k = 0; k < pnum; k++)       printf("%d ", next[k]);printf("\n");return next;
}void kmp(elemtype* s, elemtype* p) //传入两个串
{   elemtype* next = getnext(p);int i = 0;int j = 0;int flag = 1;while (flag == 1) {while (s[i] != '\0' && p[j] != '\0') {if (j == -1 || s[i] == p[j]){i++;j++;}else  j = next[j];}if (p[j] == '\0') {printf("字符串在编号%d处与模式串匹配\n", i - j);j = 0;   //匹配后模式串从头开始,继续寻找匹配点}else flag = 0;  //当字符串遍历完后才退出}
}int main() {elemtype s[] = "No Person shall be a Senator who shall not have attained to the Age of thirty Years, and been nine Years a Citizen of the United States, "" and who shall not, when elected, be an Inhabitant of that State for which he shall be chosen.";elemtype p[] = "shall";	printf("字符串为:%s\n", s);printf("模式串为:%s\n", p);kmp(s, p);
}

方法二

3.nextval

有模式串p,next数组

数组都是从1开始编号

nextval计算方法

nextval[1] = 0

对于第i位,如果p[i] 不等于 p [ next [i] ] , nextval [i] = next [i]

                   如果p [i] 等于 p [ next [i] ],则 j = next [i],继续比较p [j] = p [ next [j] ],一直向前比较,直到不等或到首位为止

例一: 

字符串‘a b a b a a b a b’ 的next为:0 1 1 2 3 4 2 3 4;nextval为:0 1 0 1 0 4 1 0 1

例二:

求字符串‘a b c a a b b c a b c a a b d a b’的next和nextval

next:     0 1 1 1 2 2 3 1 1 2 3 4 5 6 7 1 2

nextval:0 1 1 0 2 1 3 1 0 1 1 0 2 1 7 0 1 

4.时间复杂度 

由于不用回溯,主串只走一遍,加上计算next时所用的比较次数m,为O(m+n)  BF为O(n*m)

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

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

相关文章

汽车级EEPROM 存储器 M24C64-DRMN3TP/K是电可擦除可编程只读存储器?它的功能特性有哪些?

M24C64-DRMN3TP/K是一款64 Kbit串行EEPROM汽车级设备&#xff0c;工作温度高达125C。符合汽车标准AEC-Q100 1级规定的极高可靠性。 该设备可通过一个高达1MHz的简单串行I2C兼容接口访问。 存储器阵列基于先进的真EEPROM技术&#xff08;电可擦除可编程存储器&#xff09;。M2…

【力扣】543. 二叉树的直径

543. 二叉树的直径 突然间发现现在刷的题好多都和大一时学的数据结构密切相关&#xff0c;比如说这道题就用到的深度优先搜索算法。 题解&#xff1a; 以根节点为例&#xff0c;我们通过遍历左边的深度就可以得到当前左子树的长度&#xff0c;然后再遍历其右边&#xff0c;就…

吴恩达RLHF课程笔记

1.创建偏好数据集 一个prompt输入到LLM后可以有多个回答&#xff0c;对每个回答选择偏好 比如{prompt,answer1,answer2,prefer1} 2.根据这个数据集&#xff08;偏好数据集&#xff09;&#xff0c;创建reward model&#xff0c;这个model也是一个LLM,并且它是回归模型&#…

momentum2靶机

文章妙语 遇事不决&#xff0c;可问春风&#xff1b; 春风不语&#xff0c;遵循己心。 文章目录 文章妙语前言一、信息收集1.IP地址扫描2.端口扫描3.目录扫描 二&#xff0c;漏洞发现分析代码bp爆破1.生成字典2.生成恶意shell.php2.抓包 三&#xff0c;漏洞利用1.反弹shell 四…

Diffusion扩散模型学习:图片高斯加噪

高斯分布即正态分布&#xff1b;图片高斯加噪即把图片矩阵每个值和一个高斯分布的矩阵上的对应值相加 1、高斯分布 np.random.normal 一维&#xff1a; import numpy as np import matplotlib.pyplot as pltdef generate_gaussian_noise(mean, std_dev, size):noise np.ran…

低代码如何助力企业数字化转型?

目录 一、低代码开发是什么&#xff1f; 二、低代码与企业数字化转型 1&#xff09;集成化 2&#xff09;智能化 3&#xff09;定制化 三、低代码开发平台对于企业数字化转型的优势 01、提供源码 02、私有化部署 03、敏捷开发 04、拓展能力 四、低代码带来的效益 以…

量化服务器 - 后台挂载运行

服务器 - 后台运行 pip3命令被kill 在正常的pip命令后面加上 -no-cache-dir tmux 使用教程 https://codeleading.com/article/40954761108/ 如果你希望在 tmux 中后台执行一个 Python 脚本&#xff0c;你可以按照以下步骤操作&#xff1a; 启动 tmux: tmux这将会创建一个新…

绝对干货-讲讲设计模式之结构型设计模式

经典的23种设计模式种属于结构型设计模式的是装饰模式&#xff0c;适配器模式&#xff0c;代理模式&#xff0c;组合模式&#xff0c;桥接模式&#xff0c;外观模式&#xff0c;享元模式。 如果说创建型设计模式解决的是创建对象的问题&#xff0c;那么结构型模式就是通过类和…

JS逆向基础

JS逆向基础 一、什么是JS逆向&#xff1f;二、接口抓包三、逆向分析 一、什么是JS逆向&#xff1f; 我们在网站进行账号登录的时候对网页源进行抓包就会发现我们输入的密码在后台会显示为一串由字母或数字等符号&#xff0c;这就是经过加密呈现的一段加密文字&#xff0c;而分…

python脚本 链接到ssh服务器 快速登录ssh服务器 ssh登录

此文分享一个python脚本,用于管理和快速链接到ssh服务器。 效果演示 🔥完整演示效果 👇第一步,显然,我们需要选择功能 👇第二步,确认 or 选择ssh服务器,根据配置文件中提供的ssh信息,有以下情况 👇场景一,只有一个候选ssh服务器,则脚本会提示用户是否确认链…

blender径向渐变材质-着色编辑器

要点&#xff1a; 1、用纹理坐标中的物体输出连接映射中的矢量输入 2、物体选择一个空坐标&#xff0c;将空坐标延z轴上移一段距离 3、空坐标的大小要缩放到和要添加材质的物体大小保持一致

存 储 管 理

(1) 存储管理的任务和功能是什么&#xff1f; 解&#xff1a; 存储管理的主要任务是&#xff1a; 支持多道程序的并发执行&#xff0c;使多道程序能共享存储资源&#xff0c;在互不干扰的环境中并发执行。方便用户&#xff0c;使用户减少甚至摆脱对存储器的管理&#xff0c;使…

【前端】前后端通信方法与差异(未完待续)

系列文章 【Vue】vue增加导航标签 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/134965353 【Vue】Element开发笔记 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/133947977 【Vue】vue&#xff0c;在Windows IIS平台…

WPF中使用DataGrid封装组合控件TreeView+DataGrid

&#xff08;关注博主后&#xff0c;在“粉丝专栏”&#xff0c;可免费阅读此文&#xff09; wpf的功能非常强大&#xff0c;很多控件都是原生的&#xff0c;但是要使用TreeViewDataGrid的组合&#xff0c;就需要我们自己去封装实现。 我们需要的效果如图所示&#x…

Apache ShenYu 网关JWT认证绕过漏洞 CVE-2021-37580

Apache ShenYu 网关JWT认证绕过漏洞 CVE-2021-37580 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议总结 Apache ShenYu 网关JWT认证绕过漏洞 CVE-2021-37580 已亲自复现) 漏洞名称 漏洞描述 Apache ShenYu是一个异步的&#xff0c;高性能的&#x…

SpringBoot3-基础特性

文章目录 自定义 banner自定义 SpringApplicationFluentBuilder APIProfiles指定环境环境激活环境包含Profile 分组Profile 配置文件 外部化配置配置优先级 外部配置导入配置属性占位符 单元测试-JUnit5测试组件测试注解断言嵌套测试参数化测试 自定义 banner banner 就是启动…

机场信息集成系统系列介绍(7):机场航班信息显示系统FIDS

目录 一、简介 二、架构及相关功能 1、实时更新和显示航班信息 2、多屏显示与查询 3、提供登机口导航信息 4、发布机场公告 5、集成机场的其他延伸服务 6、支持多语言显示 7、监控与故障处理 8、数据分析与优化 9、与航空公司、地面代理的信息交互 10、安全保障与应…

【华为OD机试真题2023CD卷 JAVAJS】多段线数据压缩

华为OD2023(C&D卷)机试题库全覆盖,刷题指南点这里 多段线数据压缩 知识点数组栈递归矩阵循环 时间限制:1s 空间限制:256MB 限定语言:不限 题目描述: 下图中,每个方块代表一个像素,每个像素用其行号和列号表示。 为简化处理,多段线的走向只能是水平、竖直、斜向45…

GPT2代码运行,个人文本生成助手,不依赖OpenAI API调用

0.前言: 感觉GPT很好玩,所以想要有个自己搭建GPT的写法,不依赖于OpenAI,需要翻墙太麻烦了,近日日本已经结合GPT4和机器,可以让他吓人,做出丰富的表情,如果自己训练的话,会塑造出什么样的机器人尚未可知…抱着好奇的心态,去github openai下载了个gpt2的模型来玩玩(其中遇到了许多…

2016年第五届数学建模国际赛小美赛C题对超级细菌的战争解题全过程文档及程序

2016年第五届数学建模国际赛小美赛 C题 对超级细菌的战争 原题再现&#xff1a; 最近有很多关于我们抗生素耐药性危机的讨论。进化出的能够抵抗抗生素的细菌每年杀死70万人&#xff0c;越来越强大的细菌正在世界各地传播。研究人员担心&#xff0c;我们将进入一个后抗生素时代…