2023王道考研数据结构笔记第四章串

news2025/1/18 3:22:09

第四章 串

4.1 串的定义

4.1.1 串的相关概念

  1. 串:即字符串(String)是由零个或多个字符组成的有限序列。一般记为S=‘a1a2…an’ (n>=0)

    其中S是串名,单引号(注:有的地方用双引号,如Java、C,有的地方用单引号,如Python)括起来的字符序列是串的值;ai可以是字母、数字或其他字符。

  2. 串的长度:串中字符的个数 n,n = 0 时的串称为空串(用 ∅ \emptyset 表示)。

  3. 子串:串中任意个连续的字符组成的子序列。

  4. 主串:包含子串的串。

  5. 字符在主串中的位置:字符在串中的序号。(注意:位序从1开始而不是从0开始)

  6. 子串在主串中的位置:子串的第一个字符在主串中的位置 。

  7. 空串 vs 空格串 M=‘’ M是空串 N=’ ’ N是由三个空格字符组成的字符串,每个空格字符占1B

  8. 串 vs 线性表

    ① 串是一种特殊的线性表,数据元素之间呈线性关系

    ② 串的数据对象限定为字符集(如中文字符、英文字符、数字字符、标点字符等)

    ③ 串的基本操作,如增删改查等通常以字串为操作对象

4.1.2 串的基本操作

  1. StrAssign(&T, chars):赋值操作。把串 T 赋值为 chars。
  2. StrCopy(&T, S):复制操作。由串 S 复制得到串 T。
  3. StrEmpty(S):判空操作。若 S 为空串,则返回 TRUE,否则返回 FALSE。
  4. StrLength(S):求串长。返回串 S 中元素的个数。
  5. ClearString(&S):清空操作。将 S 清为空串。
  6. DestroyString(&S):销毁串。将串 S 销毁(回收存储空间)。
  7. Concat(&T, S1, S2):串联接。用 T 返回由 S1 和 S2 联接而成的新串 。
  8. SubString(&Sub, S, pos, len):求子串。用 Sub 返回串 S 的第 pos 个字符起长度为 len 的子串。
  9. Index(S, T):定位操作。若主串 S 中存在与串 T 值相同的子串,则返回它在主串 S 中第一次出现的位置;否则函数值为 0。
  10. StrCompare(S, T):比较操作。若 S>T,则返回值>0;若 S=T,则返回值=0;若 S<T,则返回值<0。

4.1.3 串的存储结构

1、静态数组实现(定长顺序存储)
#define MAXLEN 255     //预定义最大串长为255
typedef struct {
    char ch[MAXLEN];    // 每个分量存储一个字符
    int length;         // 串的实际长度
} SString;
2、动态数组实现(堆分配存储)
typedef struct {
    char *ch;       // 按串长分配存储区,ch指向串的基地址
    int length;     // 串的长度
} HString;
HString S;
S.ch=(char *)malloc(MAXLEN*sizeof(char));  //用完需要手动free
S.length=0;

在这里插入图片描述

3、块链存储表示

默认情况下存储密度低,每个节点都只能存储一个字符

解决方法:一个结点存储多个字符

在这里插入图片描述

typedef struct StringNode{
    char ch;  //存储密度低,每个字符1B,每个指针4B
    struct StringNode * next;
}StringNode,* String;

typedef struct StringNode{
    char ch[4];
    struct StringNode *next;
}StringNode,* String;      //存储密度提高

4.2 串的模式匹配

串的模式匹配:在主串中找到与模式串相同的子串,并返回其所在位置。

4.2.1 简单的模式匹配算法

思想:将主串中与模式串长度相同的字串拿出来,挨个与模式串对比

当子串与模式串某个对应字符不匹配时,就立即放弃当前子串,转而检索下一个子串

一个示例:

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0yXK4hyr-1677904184313)(数据结构.assets/03d26afdd9a945d38b8e203366f3d634.png)]

分析:

简单模式匹配算法的最坏时间复杂度是O(nm),即每个子串都要对比到最后一个字符,如下面这种情况:

  • 主串:1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2
  • 子串:1 1 1 1 1 1 1 1 2

其中,n和m分别是主串和模式串的长度。

最好的情况(对于每个子串都只需对比一次):

  • 匹配成功:O(m)
  • 匹配失败:O(n-m+1)=O(n-m)≈O(n)

4.2.2 KMP算法

朴素模式匹配算法的缺点:当某些子串与模式串能部分匹配时,主串的扫描指针i经常回溯,导致时间开销增加。

要了解子串的结构,首先需要了解以下几个概念:前缀、后缀和部分匹配值。

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

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

‘ab’的前缀是{a},后缀是{b},{a}∩{b}=∅,最长相等前后缀长度为0

'aba’的前缀为{a, ab},后缀为{a, ba}, {a, ab }∩{a, ba}={a),最长相等前后缀长度为1。

'abab '的前缀{a, ab,aba}∩后缀{b, ab, bab }={ab},最长相等前后缀长度为2。

'ababa '的前缀{a, ab,aba, abab }∩后缀{a , ba, aba, baba }={a, aba},公共元素有两个,最长相等前后缀长度为3。

故字符串’ababa’的部分匹配值为00123

接下来详解一下上面这个例子:

由上述方法求子串’abcac’的部分匹配值:

'ab’的前缀{a},后缀{b} {a}∩{b} = ∅

'abc’的前缀{a,ab}, 后缀{c, bc} {a,ab}∩{c, bc} = ∅

'abca’的前缀{a,ab,abc},后缀{a,ca,bca} {a,ab,abc}∩{a,ca,bca} = {a}

'abcac’的前缀{a,ab,abc,abca},后缀{c,ac,cac,bcac} {a,ab,abc}∩{c,ac,cac,bcac} = ∅

将其部分匹配值写成数组形式,就得到了部分匹配值(PM)的表:

编号12345
Sabcac
PM00010

接下来可以使用PM表来进行字符串匹配,其过程如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yp1IyodJ-1677904184313)(数据结构.assets/947517b937b04b7fa0c887b04eda7806.png)]

KMP算法的原理

当c与b不匹配时,已匹配’abca’的前缀a和后缀a为最长公共元素。已知前缀a与b、c均不同,与后缀a相同,故无须比较,直接将子串移动“已匹配的字符数–对应的部分匹配值”,用子串前缀后面的元素与主串匹配失败的元素开始比较即可。

在这里插入图片描述

对算法的改进

已知:右移位数=已匹配的字符数-对应的部分匹配值。写成:
M o v e = ( j − 1 ) − P M [ j − 1 ] Move=(j-1)-PM[j-1] Move=(j1)PM[j1]
现在这种情况下,我们在匹配失败时,需要去查找它前一个元素的部分匹配值,这样使用起来有点不方便,故我们可以将PM表右移一位,这样哪个元素匹配失败,则直接看它自己的部分匹配值即可。

将上例的PM表右移一位,则得到了next数组

编号12345
Sabcac
next-10001

我们注意到:

1)第一个元素右移以后空缺的用-1来填充,因为若是第一个元素匹配失败,则需要将子串向右移动一位,而不需要计算子串移动的位数。
2)最后一个元素在右移的过程中溢出,因为原来的子串中,最后一个元素的部分匹配值是其下一个元素使用的,但显然已没有下一个元素,故可以舍去

这样,上式就改写为:
M o v e = ( j − 1 ) − n e x t [ j ] Move=(j-1)-next[j] Move=(j1)next[j]
就相当于将子串的比较指针回退到:
j = j − M o v e = j − ( ( j − 1 ) − n e x t [ j ] ) = n e x t [ j ] + 1 j=j-Move=j-((j-1)-next[j])=next[j]+1 j=jMove=j((j1)next[j])=next[j]+1
但为了让公式更加简洁,我们将next数组整体加1

next数组也可以写成:

编号12345
Sabcac
next01112

最终子串指针变化公式为:
j = n e x t [ j ] j=next[j] j=next[j]

在实际匹配过程中,子串在内存里是不会移动的,而是指针在变化,书中画图举例只是为了让问题描述得更加形象。next[j]的含义是:在子串的第j个字符与主串发生失配时,则跳到子串的next[j]位置重新与主串当前位置进行比较。

【重要】求next数组,根据如下示例来学习:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BbvJ23vz-1677904184314)(数据结构.assets/a90ce7d2ecbc4b13b4554658845e9167.png)]

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

KMP算法的进一步优化

问题的产生:

在这里插入图片描述

所以引入了nextval数组,对KMP算法进行进一步优化。

故我们在模式串中,当前模式串p和对应的next数组p_next的模式串值相等时,继续查找对应p_next模式串的next数组对应的模式串,直到模式串对应的值不相等。

以下是匹配过程:

在这里插入图片描述

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

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

相关文章

4. Unity之文件资源和其它杂项

1. 资源文件 unity中的Assets文件夹下的文件都可以称为时资源文件&#xff0c;包括模型文件、材质文件、纹理贴图文件、脚本文件、音频文件等&#xff0c;如果想查看某一个文件在电脑中的保存路径&#xff0c;可以选中指定文件后&#xff0c;单击鼠标右键选择show in Explorer…

研究生退税的详细流程

本文介绍在个人所得税软件中&#xff0c;进行退税操作的详细流程。 又到了一年一度的退税时间了。作为研究生&#xff0c;由于每个月都有固定的工资&#xff0c;有时还会有导师发放的补助、国家或院校等发放的奖学金等收入&#xff0c;所以其中有时需要缴纳一部分税款&#xff…

vue-template-admin的keep-alive缓存与移除缓存

一&#xff0c;场景 A页面是表单页面&#xff0c;填写后需要跳转B页面。如果B页面不操作返回的话&#xff0c;应该能还原A页面的内容&#xff0c;而如果B页面点击提交&#xff0c;再回到A页面的时候&#xff0c;应该清除缓存。 二&#xff0c;实现方法 A页面要缓存数据&…

网络互连模型:OSI 七层模型

OSI 七层模型 七层模型&#xff0c;亦称 OSI&#xff08;Open System Interconnection&#xff09;。OSI 七层参考模型是国际标准化组织&#xff08;ISO&#xff09;制定的一个用于计算机或通信系统间网络互联的标准体系&#xff0c;一般称为 OSI 参考模型或七层模型。OSI 七层…

询问new bing关于android开发的15个问题(前景、未来、发展方向)

前言&#xff1a;new bing是基于chat-gpt的新搜索工具&#xff0c;可以采用对话方式进行问题搜索&#xff0c;经过排队等候终于可以使用new bing&#xff0c;询问了目前我最关心的关于android开发几个问题 文章目录1.如何学好android开发&#xff1f;2.android开发能做什么?3.…

最近爆火的ChatGPT核心技术演进历程

文章目录1.前言2.初识ChatGPT2.1.什么是ChatGPT2.2.ChatGPT和其他模型对比具有的特性3.ChatGPT技术演进历程3.1.Transformer&#xff08;转移学习&#xff09;和基础模型3.2.GPT-1&#xff1a;简化模型&#xff0c;使其更适合自然语言生成3.2.1.什么是GPT-13.2.1.GPT-1的优势3.…

3.crypto-config.yaml配置文件分析和cryptogen工具使用[fabric2.2]

在fabric网络启动的过程中&#xff0c;会使用使用cryptogen 工具创建组织的证书文件&#xff0c;这时候就会用到crypto-config.yaml配置文件&#xff0c;例如fabric官方测试例程test-network中就用到了crypto-config-org1.yaml&#xff0c;crypto-config-org2.yaml&#xff0c;…

java实例解析类图中【关联、组合和聚合】的区别

总目录链接==>> AutoSAR入门和实战系列总目录 文章目录 聚合Composition聚合与组合的区别关联是两个独立类之间的关系,它通过它们的对象建立关联。关联可以是一对一、一对多、多对一、多对多。在面向对象的编程中,一个对象与另一个对象通信以使用该对象提供的功能和服…

轮盘赌选择法

轮盘赌选择原理 轮盘赌选择法&#xff08;roulette wheel selection&#xff09;是最简单也是最常用的选择方法&#xff0c;在该方法中&#xff0c;各个个体的选择概率和其适应度值成比例&#xff0c;适应度越大&#xff0c;选中概率也越大。 从图中可以看出一等奖、二等奖、…

Rust学习总结之数组,元组,结构体用法

学过数据结构的都知道有这么一个公式&#xff0c;程序数据结构算法&#xff0c;好的数据结构能大大降低算法设计的复杂度&#xff0c;也能更好的为算法服务。了解一门新的计算机编程语言其数据结构是必须首先要学的&#xff0c;这有利于对该语言的理解和快速上手。本文将对Rust…

vue引入cdn Vue 优化Vue引入 cdn vue cdn Vue优化引入CDN vue 项目 CDN优化

vue引入cdn Vue 优化Vue引入 cdn vue cdn Vue优化引入CDN vue 项目 CDN优化未引入 CDN前 main.js更改CDN方式引入在 vue.config 中引入 CDNindex.html 加载 cdn资源使用CDN引入资源后的main.js如果引入CDN后 组件不生效CDN 服务商推荐未引入 CDN前 main.js // 依赖使用 npm 方…

Windows server 2003怎么安装iis?Windows server 2003安装IIS教程

Windows 2008系统服务器安装IIS之前已经分享过了&#xff0c;和Windows 2003完全不同&#xff0c;今天飞飞将详细地和你分享Windows server 2003卸载和安装IIS的步骤方法&#xff0c;希望可以帮助到你~ 1、首先进入服务器&#xff0c;确定下服务器是否有安装IIS&#xff0c;有…

漫谈数据库表设计及索引设计

一.数据库表设计 在数据库表设计上有个很重要的设计准则&#xff0c;称为范式设计。 什么是范式设计&#xff1f; 范式来自英文Normal Form&#xff0c;简称NF。MySQL是关系型数据库&#xff0c;但是要想设计—个好的关系&#xff0c;必须使关系满足一定的约束条件&#xff0c…

论如何用C语言的数组手撕一棵特殊的完全二叉树----堆

目录 0.前言 1. 用数组表示存储一棵完全二叉树 2. 数组表示的完全二叉树的性质 3. 堆的基本概念 3.1 堆的核心性质 3.2 堆顶的性质 3.3 堆的单支性质 3.4 堆的左右支关系 4. 用代码实现堆 4.1 堆类的实现 4.2 堆的初始化 4.3 堆的销毁 4.4 获取堆顶的数据 4.5 …

这款 Python 工具进行数据分析及数据可视化真的很棒啊

前言 大家好&#xff0c;今天我们以全国各地区衣食住行消费数据为例&#xff0c;来分析2022年中国统计年鉴数据&#xff0c;统计全国各地人民的消费地图&#xff0c;看看&#xff1a; 哪个省份的人最能花钱 哪个省份的人最舍得花钱 哪个省份的人最抠门 全国各地区人民在吃、穿…

一文读懂SpringBoot整合Elasticsearch(一)

&#xff08;本篇文章主要介绍Spring Boot如何整合Elasticsearch&#xff0c;包括基本配置、数据操作、搜索功能等方面。&#xff09; 一、前言 Elasticsearch是一款全文搜索引擎&#xff0c;可用于快速、准确地存储、搜索和分析大量数据。而Spring Boot是一款快速开发框架&a…

JUC【Callable、ReentrantLock、Semaphore、CountDownLatch】

JUC > java.util.concurrent JUC标准库提供的多线程安全相关的包 Callable 接口声明带返回值的任务 类似于Runnable,都是用来描述这个线程的工作的。 Callable描述的任务带返回值&#xff0c;Runnable描述的任务不带返回值 区别&#xff1a;线程封装了一个 “返回值”&#…

【项目精选】基于网络爬虫技术的网络新闻分析(视频+论文+源码)

点击下载源码 基于网络爬虫技术的网络新闻分析主要用于网络数据爬取。本系统结构如下&#xff1a; &#xff08;1&#xff09;网络爬虫模块。 &#xff08;2&#xff09;中文分词模块。 &#xff08;3&#xff09;中3文相似度判定模块。 &#xff08;4&#xff09;数据结构化存…

【Python - Matplotlib】P2 plot 折线图

Matplotlib绘制折线图折线图完整代码与效果基础折线图设定横纵坐标设置中文显示添加网格添加描述信息再添加一个城市设置两个折线图前言 上一节内容主要围绕介绍 Matplotlib 的画板结构。 链接&#xff1a;https://blog.csdn.net/weixin_43098506/article/details/129331576 本…

云HIS系统 云his系统源码 基于电子病历的医院信息平台标准建设

云HIS系统 云his系统源码 基于电子病历的医院信息平台标准进行建设 云HIS系统采用SaaS软件应用服务模式&#xff0c;提供软件应用服务多租户机制&#xff0c;实现一中心部署多机构使用。相对传统HIS单机构应用模式&#xff0c;它可灵活应对区域医疗、医疗集团、医联体、连锁诊…