【数据结构与算法设计】知识点复习-第四章-串和数组

本文详细介绍了字符串和串的基本概念,包括顺序存储和链式存储结构,以及模式匹配中的BruteForce和KMP算法。同时探讨了数组的特征、遍历方式,以及特殊矩阵尤其是稀疏矩阵的压缩存储策略。
摘要由CSDN通过智能技术生成

4.1 串的基本概念、抽象描述和分类

字符串也叫串,是由字符组成的有限序列,是一种常用的非数值数据。串的逻辑结构是线性表,串是一种特殊的线性表,其每个数据元素都是一个字符。但是串的操作特点与线性表不同,主要是对子串进行操作,通常采用顺序存储结构存储。
字符串可以表示为str=“a0a1…ai…an-1”,其中str为串名,也叫串变量; i为字符ai在串中的位序号; 双引号中的字符序列称为串值; n为串的长度; 当n=0时字符串不包含任何字符,为空串; 当字符串由一个或多个空白字符组成时为空白串。

字符串中任意个连续字符组成的子序列称为字符串的子串,此字符串为该子串的主串。子串在主串中的位置是指子串在主串中第一次出现时的第一个字符在主串中的位置。空串是任意串的子串,每个字符串都是其自身的子串,除自身外,主串的其他子串称为主串的真子串。
串的比较规则和字符的比较规则有关,字符的比较规则由所属的字符集的编码决定。两个串相等是指串长度相同并且各对应位置上的字符也相同。两个串的大小由对应位置上的首个不同字符的大小决定,字符比较次序是从头开始依次向后。当两个串的长度不等而对应位置上的字符都相同时较长的串定义为较大。

字符串是数据元素类型为字符的线性表,其抽象数据类型描述与线性表相似,又根据串在实际问题中的应用抽象出串的基本操作,可得串的抽象数据类型Python语言描述如图。

在这里插入图片描述
在这里插入图片描述
字符串的抽象数据类型Python抽象类包含了串的主要基本操作,如果要使用这个接口,还需要具体的类来实现。串的Python抽象类的实现方法主要有以下两种:
(1) 基于顺序存储的实现,为顺序串;
(2) 基于链式存储的实现,为链串。

  1. 顺序串的描述:
    顺序串与顺序表的逻辑结构相同,存储结构类似,均可用数组来存储数据元素。但串具有独特的不同于线性表的操作,属于特殊类型的线性表。下图所示为顺序串。
    在这里插入图片描述
    实现IString抽象类的顺序串类的Python语言描述如下:
    在这里插入图片描述
    在这里插入图片描述2. 顺序串基本操作的实现

    顺序串有许多基本操作,例如,求子串操作、插入操作、删除操作、连接操作、比较操作。

    下面,我们对这几个操作逐个使用Python实现。

  1. 求子串操作

求子串操作subString(begin,end)是返回长度为n的字符串中位序号从begin到end-1的字符序列,其中0≤begin≤n-1,begin<end≤n。其主要步骤如下:
(1) 检查参数begin和end是否满足0≤begin≤n-1和begin<end≤n,若不满足,抛出异常。
(2) 返回位序号为begin到end-1的字符序列。
代码如图所示
在这里插入图片描述
2) 插入操作

在这里插入图片描述
插入操作insert(i,str)是在长度为n的字符串的第i个元素之前插入串str,其中0≤i≤n。其主要步骤如下:
(1) 判断参数i是否满足0≤i≤n,若不满足,则抛出异常。
(2) 重新分配存储空间为n+m,m为插入的字符串str的长度。
(3) 将第i个及之后的数据元素向后移动m个存储单元。
(4) 将str插入到字符串从i开始的位置。

  1. 删除操作
    在这里插入图片描述
    删除操作delete(begin,end)是将长度为n的字符串的位序号为begin到end-1的元素删除,其中参数begin和end满足0≤begin≤curLen-1和begin<end≤curLen。其主要步骤如下:
    (1) 判断参数begin和end是否满足0≤begin≤curLen-1和begin< end ≤ curLen,若不满足,则抛出异常。
    (2) 将字符串位序号为end的数据元素及其之后的数据元素向前移动到位序号为begin的位置。
    (3) 字符串长度减小end-begin。

  2. 连接操作

  3. concat(str)是将串str插入到字符串的尾部,此时调用insert(curLen,str)即可实现。

  4. 比较操作

  5. 比较操作compareTo(str)是将字符串与串str按照字典序进行比较。若当前字符串较大,返回1; 若相等,返回0。若当前字符串较小,返回-1。其主要步骤如下:
    (1) 确定需要比较的字符的个数n为两个字符串长度的较小值。
    (2) 从下标0至n-1依次进行比较。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

4.2 串的模式匹配

串的模式匹配也叫查找定位,指的是在当前串中寻找模式串的过程,主要的模式匹配算法有Brute Force算法和KMP算法。
在这里插入图片描述
在这里插入图片描述

Brute Force 算法

Brute Force算法从主串的第一个字符开始和模式串的第一个字符进行比较,若相等,则继续比较后续字符; 否则从主串的第二个字符开始重新和模式串进行比较。依此类推,直到模式串的每个字符依次与主串的字符相等,匹配成功。

Brute Force算法的实现简单,但效率非常低。m为模式串的长度,n为主串的长度。
(1) 最好情况: 第一次匹配即成功,比较次数为模式串的长度m,时间复杂度为O(m)。
(2) 最坏情况: 每次匹配比较至模式串的最后一个字符,并且比较了目标串中所有长度为m的子串,此时的时间复杂度为O(m×n)。
缺点:每次匹配没有利用前一次匹配的比较结果,使算法中存在较多的重复比较,降低了算法的效率; 如果利用部分字符匹配的结果,可将算法的效率提高。因此提出了KMP算法,在下一节进行介绍。
在这里插入图片描述

KMP 算法

  1. 算法分析
    设主串为s=“aba bcabdabcabca”、模式串为p=“abcabc”,指针i、j分别指示主串和模式串所比较字符的位序号。当某次匹配不成功时有si≠pj,并且si-jsi-j+1…si-1=p0p1…pj-1。此时需要寻找前缀子串p0p1…pk-1=pj-kpj-k+1…pj-1,其中0<k<j,这时候即满足si-ksi-k+1…si-1=p0p1…pk-1,下一次匹配可直接比较si和pk。此外,为了减少比较次数,k应取最大值,即p0p1…pk-1应为满足此性质的最长前缀子串。若k不存在,下一次匹配则直接比较si和p0。

  2. K值的计算
    通过前面的分析已知,每次模式串开始比较的位置(即k的值)仅与模式串本身有关。一般用next[j]来表示pj对应的k值。
    初始时可定义next[0]=-1,next[1]=0。
    设next[j]=k,则p0p1…pk-1=pj-kpj-k+1…pj-1,k为满足等式的最大值。计算next[j+1]的值。
    (1) 若pk=pj,则存在p0p1…pk-1pk=pj-kpj-k+1…pj-1pj,此时next[j+1]=k+1。
    (2) 若pk≠pj,可以把计算next[j]的值的问题看成新的模式匹配过程,主串为p,模式串为p的前缀子串。
    出现不匹配,应将模式串的比较位置变为k′=next[k],若pj=p_(k^’ ),则next[j+1]=k′+1=next[k]+1,否则继续执行步骤(2),直到pj=pk,或者当k=0并且pj≠pk时next[j+1]=0。

在这里插入图片描述
在这里插入图片描述

4.3 数组的概念、特性、遍历

数组是n个具有相同数据类型的数据元素构成的集合,数组元素按某种次序存储在地址连续的存储单元中,是顺序存储的随机存储结构。
数组元素在数组中的位置称为数组元素的下标,用户通过下标可以访问相应的数组元素。数组下标的个数是数组的维数,具有一个下标的数组叫一维数组,具有两个下标的数组叫二维数组。一维数组的逻辑结构是线性表,多维数组是线性表的扩展。二维数组可以看成数组元素是一维数组的数组。下图所示为二维数组的矩阵表示。
在这里插入图片描述
在这里插入图片描述
数组元素被存放在一组地址连续的存储单元里,并且每个数据元素的大小相同,故只要已知首地址和每个数据元素占用的内存单元大小即可求出数组中任意数据元素的存储地址。
对于一维数组A[n],数据元素的存储地址为Loc(i)=Loc(0)+i×L(0≤i<n),其中Loc(i)是第i个元素的存储地址,Loc(0)是数组的首地址,L是每个数据元素占用的字节数。
对于二维数组,采用行优先顺序进行存储,即先存储数组的第一行,再依次存储其他各行。对于一个n×m的数组A[n][m],数组元素的存储地址为Loc(i,j)=Loc(0,0)+(i×m+j)×L,其中Loc(i,j)是第i行第j列的数组元素的存储地址,Loc(0,0)是数组的首地址,L是每个数据元素占用的字节数。
在这里插入图片描述
对二维数组进行遍历操作有两种次序,即行主序和列主序。
(1) 行主序: 以行序为主要次序,按行序递增访问数组的每行,同一行按列序递增访问数组元素。
(2) 列主序: 以列序为主要次序,按列序递增访问数组的每列,同一列按行序递增访问数组元素。
在这里插入图片描述

4.4 特殊矩阵的压缩存储

在科学技术和工程计算的许多领域,矩阵是数值分析问题研究的对象。特殊矩阵是具有许多相同数据元素或者零元素且数据元素的分布具有一定规律的矩阵,例如对称矩阵、三角矩阵和对角矩阵。
数据压缩技术是计算机软件领域研究的一个重要问题,图像、音频、视频等多媒体信息都需要进行数据压缩存储。本节将以特殊矩阵为例介绍矩阵的压缩存储。
矩阵采用二维数组进行存储,至少占用m×n个存储单元。当矩阵的阶数很大时,矩阵所占用的存储空间巨大,因此需要研究矩阵的压缩存储问题,根据不同矩阵的特点设计不同的压缩存储方法,节省存储空间,同时保证采用压缩存储的矩阵仍然能够正确地进行各种矩阵运算。
常用的矩阵压缩存储方法主要有以下两种:
(1) 对于零元素分布有规律的特殊矩阵,采用线性压缩或三角形的二维数组,只存储有规律的部分元素。
(2) 对于零元素分布没有规律的特殊矩阵,只存储非零元素。

下面,我们分别介绍一下不同类型的矩阵压缩存储方式

三角矩阵的压缩存储

三角矩阵包括上三角矩阵和下三角矩阵。假如是一个n阶矩阵,由n(n+1)/2个元素组成。当i<j时矩阵中的数据元素满足=0,矩阵为下三角矩阵; 当i>j时,矩阵中的数据元素满足=0,矩阵为上三角矩阵。
三角矩阵中具有近一半的分布有规律的零元素,所以三角矩阵采取只存储主对角线以及上/下三角部分的矩阵元素的压缩方法,主要分为以下两种:
1.线性压缩存储
2. 使用三角形的二维数组压缩存储

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
稀疏矩阵是指矩阵中的非零元素个数远远小于矩阵元素个数并且非零元素的分布没有规律的矩阵。设矩阵中有t个非零元素,非零元素占元素总数的比例称为矩阵的稀疏因子,通常稀疏因子小于0.05的矩阵称为稀疏矩阵。一般使用以下几种方法进行稀疏矩阵的压缩存储。

稀疏矩阵的非零元素三元组
稀疏矩阵的十字链表存储
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 稀疏矩阵的十字链表存储
    当稀疏矩阵中非零元素的位置或个数经常发生变化时不宜采用三元组顺序表存储结构,而应该采用链式存储结构表示。十字链表是稀疏矩阵的另一种存储结构,在十字链表中稀疏矩阵的非零元素用一个结点来表示,每个结点由5个域组成。row域存放该元素的行号,column域存放该元素的列号,value域存放该元素的值,right域存放与该元素同行的下一个非零元素结点的指针,down域存放与该元素同列的下一个非零元素结点的指针。每个非零数据元素结点既是某个行链表中的一个结点,也是某个列链表中的结点,整个稀疏矩阵构成了一个十字交叉的链表,这样的链表就称为十字链表。
    在这里插入图片描述
    下面,我们做一个例题,来深入了解不同存储结构的优缺点:
    已知A为稀疏矩阵,试从空间和时间角度比较采用二维数组和三元组顺序表两种不同的存储结构完成求运算的优缺点。
    参考答案:
    设稀疏矩阵为m行n列,如果采用二维数组存储,其空间复杂度为O(m×n); 因为要将所有的矩阵元素累加起来,所以需要用一个两层的嵌套循环,其时间复杂度也为O(m×n)。
    如果采用三元组顺序表进行压缩存储,假设矩阵中有t个非零元素,其空间复杂度为O(t),将所有的矩阵元素累加起来只需将三元组顺序表扫描一遍,其时间复杂度也为O(t)。当t<<m×n时采用三元组顺序表存储可获得较好的时空性能。

总结

(1) 字符串是数据元素类型为字符的线性表,串具有插入、删除、链接、查找、比较等基本操作。
(2) 字符串具有顺序存储结构和链式存储结构两种存储结构。字符串的顺序存储结构叫顺序串,与顺序表的逻辑结构相同,存储结构类似,均可用数组来存储数据元素。字符串的链式存储结构叫链串,和线性表的链式存储结构类似,可以采用单链表存储串值。链串由一系列大小相同的结点组成,每个结点用数据域存放字符,指针域存放指向下一个结点的指针。
(3) 串的模式匹配也叫查找定位,指的是在当前串中寻找模式串的过程,主要的模式匹配算法有Brute Force算法和KMP算法。
(4) 数组是n个具有相同数据类型的数据元素构成的集合,数组元素按某种次序存储在地址连续的存储单元中,是一种随机存储结构。
(5) 特殊矩阵是具有许多相同数据元素或者零元素且数据元素的分布具有一定规律的矩阵,例如对称矩阵、三角矩阵和对角矩阵。为了节省存储空间,对矩阵进行压缩存储。特殊矩阵的压缩存储方法是将呈现规律性分布的、值相同的多个矩阵元素压缩存储到一个存储空间。
(6) 稀疏矩阵是具有较多零元素,并且非零元素的分布无规律的矩阵。稀疏矩阵的压缩存储是只给非零数据元素分配存储空间。

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值