数据结构进阶 - 第四,五章 串、数组和广义表

数据结构进阶 - 串、数组和广义表

第四章 串(String)

4.1 串的基本概念

4.1.1 串的定义
  • 串是受限的线性表:组成串的元素只能为字符
  • 串的特点
    • 操作位置受限
    • 元素类型受限(只能是字符)
    • 是线性表的推广和受限形式
4.1.2 串的基本操作
  • 串比较
  • 连接
  • 求子串
  • 模式匹配等
4.1.3 串的存储方式
  1. 定长顺序串
  2. 堆串
  3. 块链串

4.2 模式匹配算法

4.2.1 BF算法(暴力匹配算法)

算法思想:逐个字符进行匹配,匹配失败时回退到主串的下一个位置重新开始匹配。

int StrIndex(SString s, SString t) {int i, j;if (t.len == 0) return(0);i = 0; j = 0;while (i < s.len && j < t.len) {if (s.ch[i] == t.ch[j]) {i++; j++;} else {// 匹配失败,i、j回退i = i - j + 1;j = 0;}}if (j == t.len) return i - j;else return -1;
}

时间复杂度分析

  • 最坏情况:S = ‘AAAAAAAAAAAAAAAAAAAAAAA’(长度为n),T = ‘AAAAAAAB’(长度为m)
  • 时间复杂度:T(n) = O(n×m)

算法示例

  • 主串 s = “ababcabcacbab”
  • 模式串 t = “abcac”
4.2.2 KMP算法

算法来由分析
当匹配失败时,不需要完全回退,而是利用已经匹配的信息,跳过一些不可能匹配成功的位置。

核心思想

  • 找到模式串T[0]~T[j-1]的最长相同前缀和后缀子串
  • 当匹配失败时,j指针移动到合适的位置,i指针不回退

字符串的前缀和后缀

  • 如果字符串A和B,存在A=BS,其中S是任意的非空字符串,那就称B为A的前缀
  • 例如:"Harry"的前缀包括 {“H”, “Ha”, “Har”, “Harr”}
  • 同理"Potter"的后缀包括 {“otter”, “tter”, “ter”, “er”, “r”}
  • 注意:字符串本身并不是自己的前缀或后缀

next数组定义

  • next[j]:模式串[0~j-1]的最长相同前缀和后缀的长度

next数组计算示例

j01234567
模式串abaabcac
next[j]-10011201
j0123456
模式串ABCDABD
next[j]-1000012

KMP算法实现

while (i < s.len && j < t.len) {if (j == -1 || s[i] == t[j]) {i++; j++;} else {// i不需要回溯了j = next[j]; // j回到指定位置}
}
if (j == t.len) return i - j; 
else return -1;

时间复杂度:T(n) = O(n+m)

4.2.3 KMP算法的改进(修正)

问题分析
在某些情况下,KMP算法仍存在不必要的比较。例如:

  • S:AAABAAAAAAABA
  • T:AAAABA
  • next[]:-1 0 1 2 3 0

当s(3)、t(2)匹配失败后,又从s(3)、t(1)开始匹配,匹配再次失败后从s(3)、t(0)开始匹配,依旧匹配失败。这个过程存在没有必要的回退,因为t[3]=t[2]=t[1]=t[0]=‘A’,都注定了匹配会失败。

nextval数组定义
nextval[j]中存放模式串t中,t[j]位置前最长相同前缀和后缀且满足后续字符不同的子串长度。

next→nextval转换规则

  • nextval[0] = -1
  • 当t[j] = t[next[j]]时:nextval[j] = nextval[next[j]]
  • 当t[j] ≠ t[next[j]]时:nextval[j] = next[j]

nextval数组计算示例

j012345
模式串aabaab
next-101012
nextval-1-11-1-11

4.3 课堂练习题解析

题目1:采用KMP算法在某主串S中进行模式串t='ababaaababaa’的模式匹配,next[]数组为()(下标从0开始)

答案:-1 0 0 1 2 3 1 1 2 3 4 5

题目2:采用KMP算法进行模式匹配,模式串t='ababaababaa’的next[]数组为()

答案:-1 0 0 1 2 3 1 1 2 3 2 3


第五章 数组和广义表

5.1 数组

5.1.1 数组的基本概念
  • 数组定义:数组可以看成是一般线性表的扩充
    • 一维数组即为线性表
    • 二维数组可以定义为"其数据元素为一维数组(线性表)"的线性表
    • 多维数组依次类推
5.1.2 数组的基本操作
  • 获取指定位置元素
  • 修改指定位置元素
5.1.3 数组的存储方式
  • 顺序存储:可按行或按列存储
5.1.4 数组元素地址计算

一维数组

  • 数组A[1…n],每个元素占k个字节
  • Loc(A[i]) = Loc(A[1]) + (i-1) × k

二维数组

  • 数组A[1…m][1…n],每个元素占k个字节
  • 按行存储Loc(A[i][j]) = Loc(A[1][1]) + ((i-1) × n + j-1) × k
  • 按列存储Loc(A[i][j]) = Loc(A[1][1]) + ((j-1) × m + i-1) × k

三维数组

  • 数组A[1…m][1…n][1…r],每个元素占k个字节
  • 按行-列-纵存储Loc(A[i][j][k]) = Loc(A[1][1][1]) + ((i-1) × n × r + (j-1) × r + k-1) × k
5.1.5 练习题解析

题目1:设二维数组A[6][10],每个数组元素占4个存储单元,若按行优先顺序存放的数组元素A[3][5]的存储地址是1000,则A[0][0]的存储地址为()。

解答

  • A[3][5]在数组中的位置:第3行第5列(从0开始)
  • 从A[0][0]到A[3][5]共有:3×10 + 5 = 35个元素
  • 地址差:35 × 4 = 140
  • A[0][0]的地址 = 1000 - 140 = 860

答案:860

5.2 特殊矩阵的压缩存储

5.2.1 基本概念

特殊矩阵:元素分布有规律或非零元素很多(2/3以上)的矩阵

  • 上三角矩阵
  • 下三角矩阵
  • 对称矩阵
  • 带状矩阵
  • 稀疏矩阵

压缩原则

  • 值相同的元素且分布有规律的元素只分配一个空间
  • 零元素不分配空间
5.2.2 对称矩阵

对于n×n的对称矩阵,只需存储下三角部分(含对角线):

  • 存储空间:n(n+1)/2个单元
  • 地址计算(下标从1开始):
    • 当i ≥ j时:k = i(i-1)/2 + j-1
    • 当i < j时:k = j(j-1)/2 + i-1
5.2.3 带状矩阵

对角带状矩阵(d为半个带状宽度):

  • 非零元素总个数:(2d+1)×n - (1+d)×d
  • 地址计算:需要根据具体的带状宽度来确定
5.2.4 稀疏矩阵

三元组表示法

typedef struct {int row, col;  // 行号、列号int value;     // 元素值
} Triple;

快速转置算法

  1. 统计每列非零元素个数:num[]
  2. 计算每列第一个非零元素在转置矩阵中的位置:pos[]
  3. 按行扫描原矩阵,依次放置元素

算法示例

  • 原矩阵的三元组按行序排列
  • 转置后按列序排列
  • 利用num[]和pos[]数组实现一次定位

5.3 广义表

5.3.1 广义表的定义

广义表:特殊的线性表,其特殊性在于广义表中的元素既可以是单个元素,还可以是一个广义表。

5.3.2 广义表的基本概念
  • 表头:广义表中的第一个元素
  • 表尾:除了第一个元素外,其余元素构成的广义表
5.3.3 广义表的存储结构
  • 头尾链表存储
  • 同层结点链存储
5.3.4 练习题解析

题目1:广义表((a,b,c,d))的表尾是()。
答案:( )(空表)

题目2:已知广义表LS=((a,b,c),(d,e,f)),运用head和tail函数取出LS中原子e的运算是()。
答案:head(tail(head(tail(LS))))

分析

  • tail(LS) = ((d,e,f))
  • head(tail(LS)) = (d,e,f)
  • tail(head(tail(LS))) = (e,f)
  • head(tail(head(tail(LS)))) = e

总结

重要知识点回顾

  1. 串的模式匹配

    • BF算法:简单但效率低,时间复杂度O(n×m)
    • KMP算法:利用next数组避免回退,时间复杂度O(n+m)
    • KMP改进:利用nextval数组进一步优化
  2. 数组地址计算

    • 掌握一维、二维、三维数组的地址计算公式
    • 注意下标起始位置(0或1)
  3. 特殊矩阵压缩存储

    • 对称矩阵:存储下三角,地址映射关系
    • 带状矩阵:根据带宽确定存储方式
    • 稀疏矩阵:三元组表示法,转置算法
  4. 广义表

    • 理解表头、表尾概念
    • 掌握head、tail函数的使用

考试重点

  • next数组和nextval数组的计算
  • 各种矩阵的地址计算公式
  • 稀疏矩阵的转置算法
  • 广义表的基本操作

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

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

相关文章

【力扣 困难 C】940. 不同的子序列 II

目录 题目 解法一&#xff1a;动态规划 题目 解法一&#xff1a;动态规划 int distinctSubseqII(char* s) {const int mod 1000000007;int dp[26] {0};int cnt 1;int len strlen(s);for (int i 0; i < len; i) {int new (cnt - dp[s[i] - a] mod) % mod;cnt (cnt…

【用户权限】chmod的简单使用(一)

一、用户和权限的基本概念 用户是 Linux 系统工作中重要的一环&#xff0c;用户管理包括用户与组管理。在 Linux 系统中&#xff0c;不论是由本机或是远程登录系统&#xff0c;每个系统都必须拥有一个账号&#xff0c;并且对于不同的系统资源拥有不同的使用权限。在Linux中&am…

Electron桌面程序初体验

Electron 是网页应用 (web apps) 的一个原生包装层&#xff0c;在 Node.js 环境中运行。所以需要开发者对 Node.js 和前端 Web 开发有一定地了解。下面我们就来初始化一个项目&#xff0c;试试看。 提示&#xff1a;本人使用的是npm命令&#xff0c;yarn命令也是可以的 1.初…

生信软件47 - 超低测序深度的全基因组测序cfDNA肿瘤分数估计工具ichorCNA

1. ichorCNA简介 ichorCNA是一种用于估计来自超低测序深度的全基因组测序&#xff08;ULP-WGS&#xff0c;0.1x覆盖率&#xff09;的cfDNA中肿瘤分数的工具。ichorCNA使用概率模型&#xff0c;应用隐马尔可夫模型&#xff08;HMM&#xff09;&#xff0c;以同时分割基因组&…

Python 解压缩(支持.zip/.rar/.7z格式)

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Python 解压缩&#xff08;支持.zip/.rar/.7…

龙虎榜——20250627

上证指数放量收阴线&#xff0c;回踩5天均线&#xff0c;但个股总体涨多跌少。 深证指数缩量收十字星&#xff0c;在前期压力位震荡。 2025年6月27日龙虎榜行业方向分析 1. 金融科技&#xff08;跨境支付数字安全&#xff09; 代表标的&#xff1a;吉大正元&#xff08;跨境认…

三步实现B站缓存视频转MP4格式

本期我们来实现如何将B站缓存的视频转成MP4格式&#xff0c;直接在本地播放。 首先我们在Bilibili客户端缓存一个视频&#xff0c;保存的文件如下&#xff1a; 这里有两个m4s文件&#xff0c;大的哪个是视频文件&#xff0c;小的是音频文件&#xff0c;这里我们用视频播放软件…

MySQL 与 Oracle 事务:深度解析与全面对比

在数据库管理领域&#xff0c;事务是确保数据一致性和完整性的核心机制&#xff0c;它允许用户将一系列操作视为一个不可分割的整体&#xff0c;要么全部成功执行&#xff0c;要么全部回滚。MySQL 和 Oracle 作为两款广泛使用的关系型数据库管理系统&#xff0c;它们在事务处理…

麒麟系统如何输出启动日志到串口

1、台式机系统启动日志输出到串口 &#xff08;1&#xff09;GRUB配置 编辑GRUB配置文件&#xff08;如/etc/default/grub&#xff09;&#xff0c;添加或修改以下参数&#xff1a; GRUB_CMDLINE_LINUX“consoletty0 consolettyS0,115200n8” tty0&#xff1a;表示将日志输出…

JUC:2栈和栈帧的定义

这部分内容虽然是JVM中的定义&#xff0c;但是在juc中属于底层知识&#xff0c;必须要学习 每个线程在创建时&#xff0c;就会将自身的资源存储在栈中&#xff0c;将线程需要运行的方法存放在方法区。 栈中会存储方法的局部变量、方法的参数以及方法返回的地址&#xff0c;这…

阿里云OSS上传文件Utils (@PostConstruct注解配置+Environment )

首先在 application.yaml 配置bucketName, endpoint, accessKeyId, accessKeySecret这里利用的是 spring 的生命周期, 在 bean 实例化后,使用PostConstruct注解 Environment 属性 进行spring上下文环境赋值 package com.shuai.utils;import com.aliyun.oss.*; import com.aliy…

Jetson家族横向对比:如何选择你的边缘计算设备

Jetson家族横向对比&#xff1a;如何选择你的边缘计算设备 一、边缘计算设备选型核心维度 在选择Jetson平台前&#xff0c;需明确以下关键指标&#xff1a; 算力需求&#xff1a;TOPS(INT8) / FP16精度功耗限制&#xff1a;被动散热/主动散热接口扩展&#xff1a;CSI摄像头数…

《聊一聊ZXDoc》之汽车服务导向SOME/IP

ZXDoc支持SOME/IP功能&#xff0c;通过服务导向架构实现跨域通信标准化&#xff0c;降低系统耦合&#xff0c;支持动态服务发现与调用&#xff0c;提升分布式系统扩展性和维护效率。 什么是SOME/IP&#xff1f; SOME/IP&#xff08;Scalable service-Oriented MiddlewarE ov…

Learning Semantic-Aware Knowledge Guidance for Low-Light Image Enhancement 论文阅读

学习语义感知知识引导用于低光照图像增强 摘要 低光图像增强&#xff08;LLIE&#xff09;研究如何改善照明并生成正常光照的图像。大多数现有方法通过全局和均匀的方式改进低光图像&#xff0c;而没有考虑不同区域的语义信息。如果没有语义先验&#xff0c;网络可能会容易偏…

【(Topk问题及其二叉树遍历】

Topk问题及其二叉树遍历 1.Topk问题2.二叉树的前序&#xff0c;中序&#xff0c;后序3.求二叉树的个数&#xff08;TreeSize&#xff09;。4.求二叉树的最大深度&#xff08;maxDepth&#xff09;。5.求二叉树的第K层的节点个数&#xff08;TreeKLevel&#xff09;。6.查找二叉…

AI+实时计算如何赋能金融系统?DolphinDB 在国泰君安期货年度中期策略会的演讲

6月25日&#xff0c;国泰君安期货2025年度中期策略会在上海顺利开幕。本次策略会以“观势明变&#xff0c;本固枝荣”为主题&#xff0c;特邀15位重量级行业嘉宾和52位明星分析师发表精彩观点&#xff0c;DolphinDB 受邀出席会议并作主题演讲。 实时计算如何赋能量化投研交易 …

PHP Protobuf 手写生成器,

✅ 以下是一个纯 PHP 编写的通用 Protobuf 二进制生成器&#xff0c;支持&#xff1a; varint fixed32 fixed64 length-delimited&#xff08;如字符串、嵌套 message&#xff09; 嵌套结构 (nested) 多字段 repeated ✅ 封装器代码&#xff08;可直接用&#xff09; &…

喜讯 | Mediatom斩获2025第十三届TopDigital创新营销奖「年度程序化广告平台」殊荣

6月27日&#xff0c;2025第十三届TopDigital创新营销盛典在上海圆满落幕&#xff0c;TopDigital创新营销奖获奖结果也已正式揭晓。本届TopDigital创新营销奖共有694家参展企业&#xff0c;3326件案例&#xff0c;AdMergeX旗下Mediatom媒体变现SaaS及服务平台在众多作品中脱颖而…

SQL 中 EXISTS 的原理与作用详解

平常也一直在用EXISTS 来进行逻辑判断&#xff0c;但是从来没有正经理解它&#xff0c;只知道找到有就返回True&#xff0c;没有就返回False。那么今天详细的理解一下&#xff08;主要借鉴了CSDN 其他博客文章&#xff0c;以及自己做的一个小例子&#xff09; 一、EXISTS是什么…

【Docker】解决:构建(docker build)或重新运行容器时,丢失apt-get update问题

一、解决&#xff1a;构建&#xff08;docker build&#xff09;或重新运行容器时&#xff0c;丢失apt-get update问题 在 Docker 容器中&#xff0c;每次构建&#xff08;docker build&#xff09;或重新运行容器时&#xff0c;默认情况下所有更改都会丢失&#xff0c;因为容…