【笔记】串及其应用

一、串的概念

1.串的定义

  是计算机信息处理中最常见的一种数据结构,是有限的字符序列,记作 S="a1a2an" 其中S是串名,用双引号括起来的字符序列是串值;双引号是定界符,不是串的成分; ai (1小于等于i小于等于n)是程序设计语言的字符集中的字符,称为串元素;n是串的长度,且n大于等于0。当n=0时,称为空串,记作S=“ ”(一对双引号之间没有任何字符),而S=“ ”(一对双引号之间有一个空白字符)称为空白串
  串中任意个连续的字符组成的子序列称为该串的子串。相应地,包含子串的串称为主串。通常将字符在串中的序号称为该字符在串中的位置。子串在主串的位置以子串的第一个字符在主串中的位置来表示。
  当且仅当两个串的值相等时,两个串是相等的。即只有两个串的长度相等,且串中各个对应位置的字符均相等,两个串才是相等的。

2.串的抽象数据型

  串是线性表的一种特殊情形,即当线性表的元素为字符型的情形。
  串的操作通常不是以单个元素作为操作对象,往往是一连串的字符作为操作对象。串的基本操作集合:

  • StrAssign(&S,cstr):串的赋值操作。
  • StrEmpty(S):判断串是否为空。
  • StrLength(S):求串的长度。
  • StrCopy(&T,S):串的复制。
  • StrCompare(S,T):串的比较。比较串S和T的每个字符的ASCII值的大小,如果S的值大于T,则返回1;如果S的值小于T ,则返回0;如果S的值小于T,则返回-1。
  • StrInsert(&S,pos,T):串的插入操作。
  • StrDelete(&S,pos,T):串的删除操作。
  • StrConcat(&T,S):串的连接。
  • SubString(&Sub,S,pos,len):截取子串。
  • StrReplace(&S,T,V):串的替换。
  • StrIndex(S,pos,T):返回子串的定位。
  • StrClear(&S):清空串。
  • StrDestroy(&S):销毁串。

二、串的表示

  如何表示串,既要考虑在其上的定义的操作集易于实现和执行效率的提高,又要考虑存储管理的方便和存储器的使用效率。常见的表示法有以下3种:顺序表示、堆分配表示和块链式表示。

1.串的顺序表示

  把串存放在一片连续的存储空间,即用顺序式线性表存储串,以串 S=x1x2xn 为例,将其中的字符顺序地放到数组C[1…n](字符型)中的连续位置。
  在串的顺序存储结构中,确定串的长度有两种方法, 一种是在串的末尾加上一个结束标记,如在C语言中定义串时,系统会在串值的最后自动加上‘\0’作为结束标记。另一种表示方法是用一个变量length存放串的长度,通常这种方法更为常用。

2.串的堆分配表示

  在采用静态顺序存储表示的顺序串中,在串的插入、连接、替换操作中,如果串的长度超过了MaxLen,串会被截掉一部分。为了克服静态分配的缺点,可以使用动态存储分配表示串并实现串的基本操作。
  采用堆分配存储表示的串称为堆串。堆串仍然采用一组地址连续的存储单元,存放串中的字符,但堆串中的存储空间是程序的执行过程中动态分配的。

3.串的块链式表示

  用链接表来表示串,每个结点的结构为


这里写图片描述

其中,link域为指向下个结点的指针,而data域的最简单情形就是单个字符。
  访问串中的一个子串,可以从头沿着链向后扫描,找到所希望的子串的开始元素,然后进一步沿着链得到子串的各后继元素。显然,这样访问子串的效率要比顺序表示法低。

  对于data域为单个字符的链接表示法, 存储空间的利用率很低。如果link占用两个字符位置,则每个节点中,只有 13 的空间是用来存储数据的,因此这种存储法实际上很少被采用。为了提高空间利用率,可令data域存放串中的m个连续字符,即把串中每m个连续的字符分成一组,这样即可把串分成多组,每组字符串存放在一块连续的空间中,并通过链与下一组相连。


这里写图片描述

  • 块链式串的基本操作

方式一:
  串的删除操作:只要把被删除的串全部变成“无用”符即可, 实现起来十分容易。但这样做显然要造成空间的浪费,而且降低访问效率。此时的补救办法是,每处理完一个块上的字符之后,检查该块是否已变成全“无用”的字符,若是,则将该块从链表中删除;在删除时,应找到被删除块的前导块的链域,若能在处理过程中保留前导块的地址,则删除过程会变得容易。

  串的插入操作:按照插入子串在一个存储块中的位置及插入的字符个数,可有如下3种情形:

  1. 插入子串的元素个数小于或等于串中相应位置的“无用”符个数,此时可直接以插入的子串取代“无用”符,无须做任何修改工作。
  2. 若插入的子串在一个块中最后的一个字符之后,则申请新块装入子串,链入插入点之后即可。
  3. 若插入的子串在一个块中首字符之后,最后一个字符之前,则需要先申请一个新块,将插入点所在块上的字符以插入点为界,将其后的字符装入新块,而将原来块上的插入点之后的字符换成“无用”符;然后,申请新的块,装入要插入的字符,链入上述两块之间。

  这种存储方式,若串中没有“无用符”,则存储器利用率最大可达2/3。若经过若干次插入、删除之后,存储利用率会降低,最低可能降到1/6。

方式二:
  将块链式串转换为普通字符串,完成相应的操作后再转换为块链式串。


三、串的实现

1.顺序串的实现及应用

详情请查看【练习】顺序串的实现及应用

2.串的堆分配实现

详情请查看【练习】串的堆分配实现

3.块链串的实现

详情请查看【练习】块链串的实现

四、串的模式匹配算法

  串的模式匹配也称为子串的定位操作,即查找子串在主串中出现的位置。设有主串S和子串T,如果在主串S中找到一个与子串T相相等的串,则返回串T的第一个字符在串S中的位置。其中,主串S又称为目标串,子串T又称为模式串。
  主要包括两种常用的模式匹配算法,即朴素模式匹配算法——BF算法和改进算法——KMP算法
  详情请查看【笔记】串的模式匹配算法

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值