学《数据结构》越学越聪明--第四章》》》串

串的基本概念

串(或字符串)是由零个或多个字符组成的有限序列
串中所含字符的个数称为该串的长度(或串长),含零个字符的串称为空串。

在这里插入图片描述

相等串

当且仅当两个串的长度相等并且各个对应位置上的字符串都相同时,这两个串才是相等的

在这里插入图片描述

子串

一个串中任意个连续字符组成的子序列(含空串)称为该串的子串。

真子串是不包含自身的所以子串

在这里插入图片描述

串抽象数据类型=逻辑结构+基本运算

串的几种基本运算如下:
  1. StrAssign(&s,cstr):将字符串常量cstr赋给串s,即生成其值等于cstr的串s

  2. StrCopy(&s,t):复制串。将串t赋值给串s

  3. StrEqual(s,t):判断串相等。若两个串s与t相等则返回真;否则返回假。

  4. StrLength(s):求串长。返回串s字符个数。

  5. Concat(s,t):串连接:返回由两个串s和t连接在一起形成的新串。

  6. SubStr(s,i,j):求子串。返回串s中从第i(1<=i<=n)个字符开始的、由连续j个字符组成的子串。

  7. InsStr(s1,i,s2):插入。将串s2插入到串s1的第i(1<=i<=n)个字符中,即将s2的第一个字符作为s1的第i个字符,并返回产生的新串

  8. DelStr(s,i,j):删除。从串s中删去从第i(1<=i<=n)个字符开始的长度为j的子串,并返回产生的新串。

  9. RpeStr(s,i,j,t):替换。在串s中,将第i(1<=i<=n)个字符开始的j个字符构成的子串用串替换,并返回产生的新串

  10. DispStr(s):输出。输出串s中是所有元素值

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

串和线性表有什么异同???

串是一种特殊的线性表,其中元素全部为字符型;串和线性表的操作有较大的区别;串通常以整体作为操作的对象,而线性表通常以单个元素作为操作的对象。

串的存储结构

串中元素逻辑关系和线性表的相同,所以可以采用与线性表相同的存储结构。

串的顺序存储以及基本操作实现

  • 每个单元(如4个字节)只存一个字符,称为非紧缩格式(其存储密度小)
  • 每个单元存放多个个字符,称为紧缩格式(其存储密度大)

在这里插入图片描述

非紧缩格式的顺序串定义格式

//非紧缩格式的顺序串定义格式
#define MaxSize 100
typedef struct {
	char data[MaxSize];   //用来存储字符串
	int length;   //用来存储字符串的长度
 };

在这里插入图片描述

顺序串中实现串的基本运算与顺序表的基本运算类似。

设计顺序串上实现串比较运算Strcmp(s,t)的算法。
例如:“ab”<"abcd" "abcd"<"abd"

在这里插入图片描述

//设计顺序串上实现串比较运算Strcmp(s,t)的算法
//例如:“ab” < "abcd"   "abcd" < "abd"
int Strcmp(SqString *s, SqString *t) {
	int i, c;
	if (s->length < t->length)c = t->length;   //求shet的共同长度
	else c = s->length;
	for (i <= 0;i < c;i++) {   //在共同长度内逐个比较字符
		if (s->data[i] > t->data[i]) return 1;
		else if (s->data[i] < t->data[i]) return -1;
	}
	if (s->length > t->length) return 1;  //s>t
	else if (s->length < t->length) return -1;   //s<t
	else return 0;  //s==t
}

串的链式存储以及基本操作实现

  • 连串的组织形式与一般的链表类似。
  • 链串中的一个结点可以存储多个字符。通常将连串中每个结点所存储的字符个数称为结点大小

在这里插入图片描述

链串结点大小1时,链串的结点类型定义如下:

//链串结点大小1时,链串的结点类型定义如下:
typedef struct snode{
	char data;   //用来存储字符串
	struct snode* next;  //指针域
}LiString;

在这里插入图片描述

链串中实现链串的基本运算与链表的基本运算类似。

在链串中,设计一个算法把最先出现的子串“ab”改为“xyz”。

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

//在链串中,设计一个算法把最先出现的子串“ab”改为“xyz”。
void repl(LiString* s) {
	LiString* p = s->next, * q;  //声明首结点和备用结点
	int find = 0; //定义循环用的条件
	while (p != NULL && find == 0) {   //遍历链表内元素
		if (p->data == 'a' && p == 'b') {   //找到子串
			p->data = 'x';
			p->next->data = 'z';
			q = (LiString*)malloc(sizeof(LiString));
			q->data = 'y';
			q->next = p->next;
			p->next = q;
			find = 1;
		}
		else {
			p = p->next;  
		}
	}
}

总结

串的存储结构

串是一种特殊的线性表,是线性表的一个子集。

链串只能采用单链表嘛?

  • 不一定。需要根据需要情况而定
  • 如果需要从某个结点出发前后查找,可以采用双链表。
  • 如果需要快速查找尾结点,可以采用循环双链表。

串的算法设计

串的基本算法设计
借鉴线性表的算法设计方法。顺序串和链串
串的模式匹配算法设计
BF算法 KMP算法
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雷军的小宝贝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值