串的概念及定义

本文介绍了串的概念,包括串的定义、特殊性以及基本操作。详细探讨了顺序存储结构和链式存储结构,并预告了后续将要讨论的KMP模式匹配算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

  T_T此专栏用于记录数据结构及算法的(痛苦)学习历程,便于日后复习(这种事情不要啊)。所用教材为《数据结构 C语言版 第2版》严蔚敏。


一、串的概念

  串是一种特殊的线性表,其特殊性体现在数据元素是一个字符,也就是说,串是一种内容受限的线性表。
  串(string)(或字符串)是由零个或多个字符组成的有限序列,一般记为:s= “a1a2 … an” (n>=0)。s是串的名,用双引号括起来的字符序列是串的值;ai(1<=i<=n)可以是字母、数字或其他字符;串中字符的数目n称为串的长度。
  空串(null string) :串长为0的串。
  串中任意个连续的字符组成的子序列称为该串的子串。包含所有子串的串相应地称为主串。通常称字符在序列中的序号为该字符在串中的位置。子串在主串中的位置则以子串的第一个字符在主串中的位置来表示。
  例如,有a= “BEI”、b= “JING”、 c=“BEIJING” 、d=“BEI JING”(“BEI"和"JING"中间有个空格)四个串,则它们的长度分别为3、4、7和8;并且a和b都是c和d的子串,a在c和d中的位置都是1;而b在c中的位置是4,在d中的位置则是5。
  两个串是相等的, 当且仅当这两个串的值相等。也就是说,只有当两个串的长度相等,并且各个对应位置的字符都相等时才相等。上例中的串a、b、c和d彼此都不相等。
  一个或多个空格组成的串” "称为空格串 (blank string,请注意:此处不是空串),其长度为串中空格字符的个数。为了清楚起见, 常用"∅"来表示 空串。

二、串的抽象数据类型定义

  串的逻辑结构和线性表极为相似,区别仅在于串的数据对象约束为字符集。然而,串的基本操作和线性表有很大差别。在线性表的基本操作中,大多以“单个元素”作为操作对象;而在串的基本操作中,通常以“串的整体”作为操作对象,例如,在串中查找某个子串,求取一个子串,在串的某个位置上插入一个子串,以及删除一个子串等。
  下面给出串的抽象数据类型定义:

ADT String{
数据对象: D= { ai | ai ∈ CharacterSet, i=l, 2, …, n, n>=0 }
数据关系: R1= { < ai-1, ai> | ai-1, ai ∈ D,i=2,…,n}
基本操作:
StrAssign(&T, chars)
初始条件:chars是字符串常量。
操作结果:生成一个其值等于chars的串T。
StrCopy(&T,S)
初始条件:串s存在。
操作结果:由串s复制得串T。
StrEmpty(S)
初始条件:串s存在。
操作结果:若s为空串,则返回true, 否则返回false。
StrCompare(S,T)
初始条件:串 s和T存在。
操作结果:若S>T,则返回值>0; 若S=T, 则返回值=0; 若S<T, 则返回值<0。
StrLength(S)
初始条件:串 s存在。
操作结果:返回s的元素个数,称为串的长度 。
ClearString(&S)
初始条件:串s存在。
操作结果:将s清为空串。
Concat(&T,S1,S2)
初始条件:串S1和S2存在。
操作结果:用T返回由S1和S2联接而成的新串。
SubString(&Sub,S,pos,len)
初始条件:串s存在,1<=pos<=StrLength(S)且0<=len<=StrLength(S)-pos+1。
操作结果:用Sub返回串s的第pos个字符起长度为 len的子串。
Index(S,T,pos)
初始条件:串s和T存在,T是非空串,1<=pos<=StrLength(S)。
操作结果:若主串s中存在和串T值相同的子串,则返回它在主串s中第pos个字符之后第一次出现的位置;否则函数值为0。
Replace(&S,T,V)
初始条件:串S, T和V存在,T是非空串。
操作结果:用V替换主串s中出现的所有与T相等的不重叠的子串。
Strlnsert(&S,pos,T)
初始条件:串s和T 存在,1<=pos<=StrLength(S)+l。
操作结果:在串 s 的第 pos 个字符之前插入串 T。
StrDelete(&S,pos,len)
初始条件:串 S 存在,1<=pos<=StrLength(S)-len+1。
操作结果:从串 s 中删除第 pos 个字符起长度为 len 的子串。
DestroyString (&S)
初始条件:串s存在。
操作结果:串s被销毁。
}ADT String

三、串的存储结构

  串具有两种基本存储结构:顺序存储和链式存储。但考虑到存储效率和算法的方便性, 串多采用顺序存储结构。

1.顺序存储结构

  类似于线性表的顺序存储结构, 用一组地址连续的存储单元存储串值的字符序列。

//----- 串的定长顺序存储结构- - ---
#define MAXLEN 255   //串的最大长度
typedef struct { 
char ch[MAXLEN+1];   //存储串的一维数组
int length;          //串的当前长度
} SString;

  为了便于说明问题,串从下标为1的数组分量开始存储,下标为0的分量闲置不用或用于存储串长,从而可以简化为:

//----- 串的定长顺序存储结构- - ---
#define MAXLEN 255   //串的最大长度
typedef struct { 
char ch[MAXLEN+1];   //存储串的一维数组
} SString;

  上述定义方式是静态的,不利于串的内存空间变化,因此最好是根据实际需要, 在程序执行过程中动态地分配和释放串空间。
  在C语言中, 存在一个称之为 " 堆 " (Heap)的自由存储区,可以为每个新产生的串动态分配一块实际串长所需的存储空间,若分配成功,则返回一个指向起始地址的指针,作为串的基址,同时为了以后处理方便,约定串长也作为存储结构的一部分。 这种字符串的存储方式也称为串的堆式顺序存储结构, 定义如下:

//----- 串的堆式顺序存储结构---- -
typedef struct{ 
char *ch;     //若是非空串,则按串长分配存储区,否则 ch 为 NULL
int length;   //串的当前长度
}HString;

2.链式存储结构

  虽然链式结构便于不同串的联结,但其存储密度较低。如果在一个节点上存储多个字符,虽然可以提高存储密度,但由于串的操作通常以子串整体形式实现,对于某个子串,其不同部分可能存储在不同结点上,操作效率降低、实现难度增大;如果将每个子串分配到一个结点上,虽然便于操作,但由于不同子串长度不同,必然存在结点,其数据域没有完全利用,存储密度降低。
  整体而言,串的链式存储不如串的顺序存储灵活,因此不再深入。


总结

  路漫漫其修远兮,吾将上下而摆烂。在下一节中,我们将迎来第一个算法——串的模式匹配算法,KMP算法。(好耶!)
  有任何疑问和补充,欢迎交流。(但我显然不会5555…)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值