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

数据结构——串(字符串)

文章目录

    • **一 串的定义和实现**
      • **1 定义**
      • **2 串的存储结构**
        • **2.1 定长顺序存储表示**
        • **2.2 堆分配存储表示**
        • **2.3 块链存储表示**
      • **3 串的基本操作**
    • **二 串的模式匹配**
      • **1 简单的模式匹配算法**
      • **==2 串的模式匹配算法——KMP算法==**
        • **2.1 字符串的前缀,后缀和部分匹配值**
        • **2.2 KMP算法的原理**
        • **2.3 KMP算法的优化**

一 串的定义和实现

1 定义

串是由零个或多个字符组成的有限序列,可以是字母,数字或者其他字符

由一个或多个空格组成的串称为空格串(空格也是一种符号)

如“hello world 232@#%^&”

2 串的存储结构

2.1 定长顺序存储表示

#define maxline 255
typedef struct
{char ch[maxline];int length;
}Sstring;

一组连续的存储单元

超过的长度会发生截断;一般字符串的结尾都有一个隐含的“\0”,不计入长度

在这里插入图片描述

2.2 堆分配存储表示

仍是一组连续的存储单元,但是存储空间是执行过程中动态分配的

typedef struct
{char *ch;int length;
}Hstring;

2.3 块链存储表示

每个结点可以存放一个字符,也可以存放多个字符

每个结点称为块,整个链表称为块链结构

最后一个结点占不满时通常用#补上

在这里插入图片描述

3 串的基本操作

Strassign(&T,chars);            \\T赋值到chars
Strcopy(&T,S);                  \\S复制到T
Strempty(S);                    \\判空
Strcompare(S,T);                \\比较ST,S>T返回值大于0
Strlength(S);                   \\求串长
Substring(&Sub,S,pos,len);      \\用sub返回s从pos位置长度为len的子串
Concat(&T,S1,S2);               \\T返回s1和s2的串接
Index(S,T);                     \\若S中存在T相同的子串,返回第一次出现的位置,否则为0
Clearstring(&S);                \\清空
Destroystring(&S);              \\销毁

二 串的模式匹配

1 简单的模式匹配算法

模式匹配:子串的定位操作,求的是子串在主串中的位置

采用定长顺序存储结构

暴力算法

int Index(Sstring S,Sstring R)
{int i =1,j=1;while(i<=S.length && j<= T.length){if(S.ch[i]==T.ch[j]){i++;j++;}else{i=i-j+2;           \\比对失败倒退下标j=1;}}if(j >T.length)return i-T.length;     \\找到了位置并返回elsereturn 0;              \\没找到
}

时间复杂段:O(mn),m,n分别是子串和主串的长度

算法思想:主串和子串的字符一一对比,如果不对,子串倒退到一开始,主串倒退到刚刚比较的的下一个位置

当子串为“00001”,主串为“0000000000000000000000001”时,可以预想到查找效率极低,需要匹配到最后一个位置才能找到

在这里插入图片描述

2 串的模式匹配算法——KMP算法

从刚刚的例子可以看出第四次和第五次是不需要进行的,因为从第三次的结果可以看出“b” “c” “a”是无需进行比较的,仅需向右滑动三个位置

如果已匹配相等的前缀序列中有某个后缀正好是子串的前缀,那么就可以将子串向后滑动到与这些相等字符对齐的位置

2.1 字符串的前缀,后缀和部分匹配值

前缀:除最后一个字符意外,字符串的所有头部子串

后缀:除第一个字符外,字符串的所有尾部子串

部分匹配值:字符串的前缀和后缀的最长相等前后缀长度,以下记为PM

‘a’:前后缀为空,PM=0

‘ab’:前缀‘a’,后缀‘b’,‘a’ ⋂ \bigcap ‘b’= ∅ \varnothing ,PM=0

‘aba’,前缀‘a,ab’,后缀‘a,ba’,并集为‘a’,PM=1

‘abab’,前缀‘a,ab,aba’,后缀‘b,ab,bab’,并集‘ab’,PM=2

‘ababa’,前缀‘a,ab,aba,abab’,后缀‘a,ba,aba,baba’,并集‘a,aba’,PM=3

所以‘ababa’的部分匹配值为00123

那么刚刚例子中abcac的PM就为

编号12345
Sabcac
PM00010

采用PM的移动算法:

移动位数 = 已匹配的字符数 - 最后一个匹配成功的字符对应的PM

在这里插入图片描述

主串没有回退,时间复杂度:O(n+m),大大提高了效率

2.2 KMP算法的原理

通过上述的部分匹配值可以得出匹配失败时主串对比的移动位数

写成式子:move=(j-1)-PM[j-1]

但是失败时总是去找匹配失败的上一个PM值,使用起来不太方便,所有将所有PM表右移一位,得到next数组

编号12345
Sabcac
PM-10001

第一个元素右移后用-1来填充,因为若是第一个元素匹配失败,只需要将子串向右移动一位再比较,不需要计算子串移动的位数

最后一个元素溢出,但上一个PM本来就是计算下一个元素的,所有这个PM不存在下一个元素,可以舍弃

移动位数:move = (j-1) - next[j]

所以指针J回退的位置:j=j-move=next[j]+1

为了再使得公式简单简洁,再把next数组整体+1

编号12345
Sabcac
PM01112

最终的子串指针变化公式j=next[j]

next[j]的含义:在子串的第j个字符与主串发生失配时,则跳到子串的next[j]位置重新与主串当前位置进行比较

怎么推理next数组的一般公式?

假设主串为S1S2……Sn,模式串为p1p2……pm,当主串的第i个字符与模式串的第j个字符失配,子串应向右滑动多远,然后与模式串的那个字符比较?

假设此时应该与第k(k<j)个字符继续比较,则模式串的前k-1个字符的子串必须满足下列条件,且不可能存在k,>k满足下列条件

​ ‘p1p2……pk-1’=‘ pj-k+1pj-k+2……pj-1

(1)若满足上述条件,失配时,将模式向右滑动至模式中第k个字符和主串第i个字符对齐,此时模式中前k-1个字符的子串必定与主串中第i个字符之前长度为k-1的子串相等,只需从模式第k个字符与主串第i个字符继续比较即可

在这里插入图片描述

(2)不满足上述条件时(k=1),直接将模式串右移j-1位,让主串的第i个字符与模式串第一个字符对比,此时右移位数最大

(3)若模式串的第一个子串就与主串的第i个字符失配时,规定next[1]=0;模式串右移一位,从主串的下一个位置i+1与模式串的第一个位置继续对比

即next函数的公式为

在这里插入图片描述

首先可知next[1]=0,next[j]=k;那next[j+1]为多少呢,有两种情况:

(1)若pk=pj,则满足条件 ‘p1p2……pk-1’=‘ pj-k+1pj-k+2……pj-1’ ,所以next[j+1]=k+1,即next[j+1]=next[j]+1

(2)若pk ≠ \neq =pj,不满足上述条件,则把p1…pk向右滑动到next[k]与pj比较,若pnext[k]与pj还是不匹配,继续找更短的相等前后缀,继续用pnext[next[k]]比较,直到更小的k’满足条件,next[j+1]=k’+1;如果不存在k,则令next[j+1]=1

举例说明:

j123456789
模式abaabcaba
next[j]011223123

j=1:初始next[1]=0

j=2:往前不存在p0与p1相等,则next[2]=1

j=3:往前不存在p与p2相等,则next[3]=1

j=4:通过p3的next判断pnext[3]即p1=p3,则next[4]=next[3]+1=2,同时也是next[4]=k+1=2

j=5:通过pnext[next[4]]即p1=p4,则k=next[next[4]]=1,next[5]=k+1=2

j=6:p5=pnext[2],则k=2,next[6]=k+1=3

j=7:不存在p与p6相等,则next[7]=1

j=8:p7=p1,则k=1,next[8]=1+1=2

j=9:p8=p2,则k=2,next[9]=2+1=3

代码如下

void getnext(Sstring T,int next[])
{int i =1,j=0;next[1]=0;while(i<T.length){if(j==0||T.ch[i]==T.ch[j]){i++;j++;next[i]=j;}elsej = next[j];}}int IndexKMP(Sstring S,Sstring T,int next[])
{int i =1,j=1;while(i<=S.length && j<= T.length){if(j==0||S.ch[i]==T.ch[j]){i++;j++;}else{j=next[j];}}if(j>T.length){return i-T.length;}else{return 0;}
}

2.3 KMP算法的优化

前面的next数组仍有缺项,比如‘aaaab ’和‘aaabaaaab’ 匹配时

在这里插入图片描述

不应该出现pj=pnext[j],当pj ≠ \neq =sj时,下次匹配必然还是pnext[j]与sj比较,毫无意义

如果出现pj=pnext[j],需要再次递归,将next[j]修正为next[next[j]],直到不相等,新数组命名为nextval

void getnextval(Sstring T,int nextval[])
{int i =1,j=0;nextval[1]=0;while(i<T.length){if(j==0||T.ch[i]==T.ch[j]){i++;j++;if(T.ch[i]!=T.ch[j])nextval[i]=jelsenextval[i]=nextval[j];}elsej = nextval[j];}}

相关文章:

数据结构——串(字符串)

文章目录 **一 串的定义和实现****1 定义****2 串的存储结构****2.1 定长顺序存储表示****2.2 堆分配存储表示****2.3 块链存储表示** **3 串的基本操作** **二 串的模式匹配****1 简单的模式匹配算法****2 串的模式匹配算法——KMP算法****2.1 字符串的前缀&#xff0c;后缀和…...

Seata服务端的启动过程 学习记录

1.ServerRunner ServerRunner类实现了CommandLineRunner与DisposableBean接口&#xff0c;将会在Spring容器启动和关闭的时间&#xff0c;分别执行 run 和 destory 方法。 而seata服务端的启动过程&#xff0c;都藏在run方法中 2.整体流程 io.seata.server.Server#start pu…...

Log4J

引言 为什么要用日志? --> 方便调试代码 什么时候用?什么时候不用? ​ 出错调试代码时候用 生产环境下就不需要,就需要删除 怎么用? --> 输出语句 一、Log4J 1.1 介绍 ​ log4j是Apache的一个开放源代码的项目&#xff0c;通过使用log4j&#xff0c;我们可以控…...

【零基础学机器学习 5】机器学习中的分类:什么是分类以及分类模型

&#x1f468;‍&#x1f4bb; 作者简介&#xff1a;程序员半夏 , 一名全栈程序员&#xff0c;擅长使用各种编程语言和框架&#xff0c;如JavaScript、React、Node.js、Java、Python、Django、MySQL等.专注于大前端与后端的硬核干货分享,同时是一个随缘更新的UP主. 你可以在各个…...

目标检测算法:Faster-RCNN论文解读

目标检测算法&#xff1a;Faster-RCNN论文解读 前言 ​ 其实网上已经有很多很好的解读各种论文的文章了&#xff0c;但是我决定自己也写一写&#xff0c;当然&#xff0c;我的主要目的就是帮助自己梳理、深入理解论文&#xff0c;因为写文章&#xff0c;你必须把你所写的东西表…...

基于Python的接口自动化-Requests模块

目录 引言 一、模块说明 二、Requests模块快速入门 1 发送简单的请求 2 发送带参数的请求 3 定制header头和cookie 4 响应内容 5 发送post请求 6 超时和代理 三、Requests实际应用 引言 在使用Python进行接口自动化测试时&#xff0c;实现接口请求…...

Vue框架中监测数组变化的方法

在 Vue 中&#xff0c;如果直接对数组进行操作&#xff0c;比如使用下标直接修改元素&#xff0c;数组长度不变时&#xff0c; Vue 是无法监测到这种变化的&#xff0c;导致无法触发视图更新。针对该问题&#xff0c;总结如下解决方法&#xff1a; 一、使用 Vue.js 提供的方法…...

PHP isset()函数使用详解,PHP判断变量是否存在

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 isset 一、判断变量是否存在二、判断变量是否为NUL…...

2021~2022 学年第二学期《信息安全》考试试题(A 卷)

北京信息科技大学 2021~2022 学年第二学期《信息安全》考试试题&#xff08;A 卷&#xff09; 课程所在学院&#xff1a;计算机学院 适用专业班级&#xff1a;计科1901-06&#xff0c;重修 考试形式&#xff1a;(闭卷) 一、选择题&#xff08;本题满分10分,共含10道小题,每小题…...

通俗讲解元学习(Meta-Learning)

元学习通俗的来说&#xff0c;就是去学习如何学习&#xff08;Learning to learn&#xff09;,掌握学习的方法&#xff0c;有时候掌握学习的方法比刻苦学习更重要&#xff01; 下面我们进行详细讲解 1. 从传统机器学习到元学习 传统的机器学中&#xff0c;我们选择一个算法&…...

生成全球定位系统、伽利略和北斗二号的Matlab代码及实际数据捕获文件,为测试功能提供完整信号与频谱

使用Matlab生成和分析GNSS信号&#xff08;第一部分&#xff09; 全球导航卫星系统(Global Navigation Satellite System, GNSS)是一个提供全球覆盖的&#xff0c;定位、导航、时间传递服务的系统。由全球定位系统(GPS)&#xff0c;俄罗斯的格洛纳斯(GLONASS)&#xff0c;欧洲…...

Android 14 版本变更总览

Android 14 版本 Android 14 总览Android 14 功能和变更列表行为变更&#xff1a;所有应用行为变更&#xff1a;以 Android 14 或更高版本为目标平台的应用功能和 API 概览 Android 14 总览 https://developer.android.google.cn/about/versions/14?hlzh-cn 文章基于官方资料…...

内网安全:Cobalt Strike 工具 渗透多层内网主机.(正向 || 反向)

内网安全&#xff1a;Cobalt Strike 工具 渗透多层内网主机. Cobalt Strike 是一款以 metasploit 为基础的 GUI 的框架式渗透工具&#xff0c;又被业界人称为 CS。拥有多种协议主机上线方式&#xff0c;集成了端口转发&#xff0c;服务扫描&#xff0c;自动化溢出&#xff0c;…...

ChatGPT 五个写论文的神技巧,让你的老师对你刮目相看!

导读&#xff1a;ChatGPT这款AI工具在推出两个月内就累积了超过1亿用户。我们向您展示如何使用ChatGPT进行写作辅助&#xff0c;以及其他一些有用的写作技巧。 本文字数&#xff1a;2000&#xff0c;阅读时长大约&#xff1a;12分钟 ChatGPT这款AI工具在推出两个月内就累积了超…...

模型服务文档自动生成,要素追溯关联、结构规范易读|ModelWhale 版本更新

整装待发的初夏&#xff0c;ModelWhale 持续聚焦 AI for Science&#xff0c;针对大模型等前沿带来了新一轮的版本更新&#xff0c;期待为你提供更好的使用体验。 本次更新中&#xff0c;ModelWhale 主要进行了以下功能迭代&#xff1a; • 新增 模型服务文档自动生成&#xf…...

《微服务实战》 第三十一章 ShardingSphere - ShardingSphere-JDBC

前言 Apache ShardingSphere 是一款分布式的数据库生态系统&#xff0c; 可以将任意数据库转换为分布式数据库&#xff0c;并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。 Apache ShardingSphere 设计哲学为 Database Plus&#xff0c;旨在构建异构数据库上层的…...

【论文阅读】Twin neural network regression is a semi- supervised regression algorithm

论文下载 GitHub bib: ARTICLE{,title {Twin neural network regression is a semi- supervised regression algorithm},author {Sebastian J Wetzel and Roger G Melko and Isaac Tamblyn},journal {Machine Learning: Science and Technology},year {2022},volum…...

java之反射机制和注解(更新中......)

Reflect在文档中的位置&#xff1a; 文档链接&#xff1a;https://docs.oracle.com/javase/8/docs/api/index.html 用于获取类或对象的反射信息。 常用的反射机制重要的类&#xff1a; java.lang.Class&#xff1a;整个字节码&#xff0c;代表一个类型。包含了以下三块内容&a…...

【Unity入门】25.入门结课Demo--神鸟大战怪兽

【Unity入门】入门结课Demo--神鸟大战怪兽 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity入门系列博客&#xff0c;所学知识来自B站阿发老师~感谢 (一) 前言 经过了两个月的学习&#xff0c;我们也顺利的完成了入门课程&#xff0c;最后就用一个Demo作为我们的结课句号吧&am…...

HTTP协议基本格式

HTTP即HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09;&#xff0c;HTTP基于TCP/IP协议传输数据。 目录 Chrome抓包Fiddler代理抓包HTTP协议格式HTTP请求首行URL方法Get方法Post方法Get与Post的区别 请求报头中的属性Cookie和SessionCookie与Session的区别…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...