数据结构学习笔记——顺序存储结构实现串

Posted 晚风(●•σ )

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构学习笔记——顺序存储结构实现串相关的知识,希望对你有一定的参考价值。

目录

一、串的相关概念

  • 串由零个或多个字符组成的有限序列,其数据元素就是字符,它是一种特殊的线性表。由任意多个连续的字符组成的子序列称为串的子串,包含子串的串称为主串,线性表是以单个元素进行相关操作,而串是以子串进行相关操作的。
  • 串的长度等于0时的串称为空串,空串是任意串的子串,任意串是自身的子串。

二、定长顺序存储和变长分配存储

(一)定长顺序存储
通过静态数组实现定长顺序存储,一组地址连续的存储单元存储串值的字符序列,其中每个串都被分配一个固定长度的ch[MAXLEN]数组。

#include<stdio.h>
#define MAXLEN 255
typedef struct
	char ch[MAXLEN];	//为每个串分配一个固定长度的数组 
	int length;		//串的实际长度 
SString;

(二)变长分配存储(堆分配存储)
而当序列的长度超过事先限定的MAXLEN值时,则此时可以采用变长分配存储,适用于串长较灵活的情况。与定长顺序存储一样,也是采用一组地址连续的存储单元来存放串值的字符序列,但堆分配存储的存储空间是动态分配的,通过malloc()和free()函数来完成动态存储的分配和释放。

  • 分配成功时,返回一个指向起始地址的指针*ch作为串的基地址,它指向动态分配存储区首地址的字符指针,若分配失败则返回NULL。
//堆分配存储的定义 
#include<stdio.h>
#include<stdlib.h>
typedef struct
	char *ch;	//指向串的基地址 ,即指向动态分配存储区首地址的字符指针 
	int length;		//串的实际长度 
HString;

HString S;
S.ch=(char *)malloc(MAXLEN*sizeof(char));	//malloc动态分配 
S.length=0;		//初始化length串长度 

三、串的初始化

/*初始化串S*/
void InitString(SString &S) 
	S.length = 0;		

四、判断串是否为空

/*判断串S是否为空*/
bool EmptyString(SString &S) 
	if (S.length == 0)
		return false;
	else
		return true;

五、串的建立

串的建立中,通过从键盘读入一个字符串并赋给S,如下代码:

/*串的建立*/
void CreateString(SString &S) 
	printf("请输入一个字符串:\\n");
	scanf("%s",&S.ch);

六、串的遍历输出

/*串的遍历输出*/
void PrintString(SString S) 
	for(int i=0; i<S.length; i++)
		printf("%c ", S.ch[i]);

七、求串的长度

通过while()循环,每次读取一个字符然后S.length++,最后得到串的长度,如下代码:

/*求串的长度*/
bool LengthString(SString &S) 
	if(S.ch[0]=='\\0')
		return false;	//空串报错
	while(S.ch[S.length]!='\\0')
		S.length++;
	printf("该串的长度为:%d\\n",S.length);
	return true;

八、求串的子串

求子串的操作是从串S的第某位起,length为相关长度的子串S1,也就是截取串S的部分,首先要判断求的子串的相关参数是否正确合法,然后通过循环依次将串S的相应内容赋值给新串(子串)中 ,代码如下:

/*求子串*/
//求串S的第pos位置开始,长度为length的子串,并将其存入到串Sub中
int SubString(SString &S,SString &Sub,int pos,int length) 
	if(pos<1||pos>S.length||length<1||length>S.length-pos+1) 
		return false;	//以上情况报错 
	 else 
		for(int i=0; i<length; i++)
			Sub.ch[i]=S.ch[pos+i-1];	//依次将串S的相应内容赋值给新串(子串)中 
		Sub.length=length;	//新串(子串)的长度 
		return true;
	

例已知串S“ABCDEFGH”,求串S从第2位起,长度为4的子串子串,并将其存入到串S1中,最后输出串S1。

代码如下:

#include<stdio.h>
#define MAXLEN 255
typedef struct 
	char ch[MAXLEN];	//为每个串分配一个固定长度的数组
	int length;		//串的实际长度
 SString;

/*初始化*/
void InitString(SString &S) 
	S.length = 0;


/*求串的长度*/
bool LengthString(SString &S) 
	if(S.ch[0]=='\\0')
		return false;	//空串报错
	while(S.ch[S.length]!='\\0')
		S.length++;
	printf("该串的长度为:%d\\n",S.length);
	return true;


/*串的建立*/
void CreateString(SString &S) 
	printf("请输入一个字符串:\\n");
	scanf("%s",&S.ch);


/*串的遍历输出*/
void PrintString(SString S) 
	for(int i=0; i<S.length; i++)
		printf("%c ", S.ch[i]);


/*求子串*/
//求串S的第pos位置开始,长度为length的子串,并将其存入到串Sub中
int SubString(SString &S,SString &Sub,int pos,int length) 
	if(pos<1||pos>S.length||length<1||length>S.length-pos+1) 
		return false;	//以上情况报错 
	 else 
		for(int i=0; i<length; i++)
			Sub.ch[i]=S.ch[pos+i-1];	//依次将串S的相应内容赋值给新串(子串)中 
		Sub.length=length;	//新串(子串)的长度 
		return true;
	


/*主函数*/
int main() 
	int pos,length;
	SString S,S1;
	InitString(S);	//初始化
	CreateString(S);	//串的创建
	LengthString(S);	//求串的长度
	PrintString(S);	//遍历串 
	printf("\\n"); 
	printf("请输入从串的第几个字符开始求子串pos以及要取出的子串长度length:\\n");
	scanf("%d %d",&pos,&length);
	SubString(S,S1,pos,length);
	LengthString(S1);	
	PrintString(S1);	

运行结果如下:

九、插入子串

插入子串的操作是在串S的第i个位置进行插入,插入子串S1,首先也是要判断插入的位置是否合法(要注意插入后两个串的长度相加之和是否超过存储空间长度),将从第i位开始的字符都向后移动S1串长度,然后通过循环依次将子串S1插入到串S的第i位开始的依次位置处,最后再修改串S的长度,并在新串S的末尾加上字符串结束标志“\\0”,代码如下:

/*插入子串*/
bool InsertString(SString &S,SString &S1,int i) 
	int n;
	if(i>S.length+1||S.length+S1.length>MAXLEN)		//报错 
		return false;
	else 
		for(n=S.length-1; n>=i-1; n--)	//从第i位开始的字符都向后移动S1串长度
			S.ch[S1.length+n]=S.ch[n];
		for(n=0; n<S1.length; n++)	//将子串S1依次插入到串S的第i位开始的依次位置处
			S.ch[i+n-1]=S1.ch[n];
		S.length=S.length+S1.length;	//修改串S的长度
		S.ch[S.length]='\\0';	//加上字符串结束标志\\0 
		return true;
	

例已知串S“aaaaaa”和串S1“bbb”,将串S1插入至串S的第二位,最后输出串S。

代码如下:

#include<stdio.h>
#define MAXLEN 255
typedef struct 
	char ch[MAXLEN];	//为每个串分配一个固定长度的数组
	int length;		//串的实际长度
 SString;

/*初始化*/
void InitString(SString &S) 
	S.length = 0;


/*求串的长度*/
bool LengthString(SString &S) 
	if(S.ch[0]=='\\0')
		return false;	//空串
	while(S.ch[S.length]!='\\0')
		S.length++;
	printf("该串的长度为:%d\\n",S.length);
	return true;


/*串的建立*/
void CreateString(SString &S) 
	printf("请输入一个字符串:\\n");
	scanf("%s",&S.ch);


/*串的遍历输出*/
void PrintString(SString S) 
	for(int i=0; i<S.length; i++)
		printf("%c ", S.ch[i]);


/*插入子串*/
bool InsertString(SString &S,SString &S1,int i) 
	int n;
	if(i>S.length+1||S.length+S1.length>MAXLEN)		//报错 
		return false;
	else 
		for(n=S.length-1; n>=i-1; n--)	//从第i位开始的字符都向后移动S1串长度
			S.ch[S1.length+n]=S.ch[n];
		for(n=0; n<S1.length; n++)	//将子串S1依次插入到串S的第i位开始的依次位置处
			S.ch[i+n-1]=S1.ch[n];
		S.length=S.length+S1.length;	//修改串S的长度
		S.ch[S.length]='\\0';	//加上字符串结束标志\\0 
		return true;
	


/*主函数*/
int main() 
	int i;
	SString S,S1;
	printf("请输入串S!");
	InitString(S);	//初始化
	CreateString(S);	//串S的创建
	printf("请输入要插入的子串S1!");
	InitString(S1);	//初始化
	CreateString(S1);	//串S1的创建
	LengthString(S);
	PrintString(S);
	printf("\\n"); 
	LengthString(S1);
	PrintString(S1);
	printf("\\n"); 
	printf("请输入从串的第几个字符插入子串i:");
	scanf("%d",&i);
	InsertString(S,S1,i);	//插入子串 
	printf("插入子串后的串S的长度,");
	LengthString(S);
	PrintString(S);

运行结果如下:

十、删除子串

删除子串的操作也就是删除从串S的某一位置起连续的字符,首先要判断删除的位置以及删除的串长度是否正确合法,否则报错,将第i+j-1位的字符向前移动到第i位依次移动字符,最后再修改串S的长度,并在新串S的末尾加上字符串结束标志“\\0”,例如删除第2位长度为4的字符,串S总长度为8,删除后原先第5位的字符向前移动到第2位上,原先第6位的字符向前移动到第3位上,……,代码如下:

/*删除子串*/
bool DeleteString(SString &S,int i,int j) 
	if(i+j-1>S.length)	//所删除的子串超过串S长度,则报错
		return false;
	else 
		for(int n=i+j-1; n<S.length; n++,i++)
			S.ch[i-1]=S.ch[n];	//从串的第i位删除长度为j多个字符
		S.length=S.length-j;	//修改串S的长度
		S.ch[S.length]='\\0';	//加上字符串结束标志\\0 
		return true;
	

例已知串S“ABCDEFGHIJK”,删除串S中从第2位起,长度为6的子串,最后输出串S。

代码如下:

#include<stdio.h>
#define MAXLEN 255
typedef struct 
	char ch[MAXLEN];	//为每个串分配一个固定长度的数组
	int length;		//串的实际长度
 SString;

/*初始化*/
void InitString(SString &S) 
	S.length = 0;


/*求串的长度*/
bool LengthString(SString &S) 
	if(S.ch[0]=='\\0')
		return false;	//空串
	while(S.ch[S.length]!='\\0')
		S.length++;
	printf("该串的长度为:%d\\n",S.length);
	return true;


/*串的建立*/
void CreateString(SString &S) 
	printf("请输入一个字符串:\\n");
	scanf("%s",&S.ch);


/*串的遍历输出*/
void PrintString(SString S) 
	for(int i=0; i<S.length; i++)
		printf("%c ", S.ch[i]);


/*删除子串*/
bool DeleteString(SString &S,int i,int j) 
	if(i+j-1>S.length)	//所删除的子串
		return false;
	else 
		for(int n=i+j-1; n<S.length; n++,i++)
			S.ch[i-1]=S.ch[n];	//从串的第i位删除长度为j多个字符
		S.length=S.length-j;	//修改串S的长度
		S.ch[S.length]='\\0';	//加上字符串结束标志\\0 
		return true;
	


/*主函数*/
int main() 
	int i,j;
	SString S;
	InitString(S);	//初始化
	CreateString(S);	//串的创建
	LengthString(S);	//求串的长度
	PrintString(S);	//遍历串
	printf("\\n");
	printf("请输入从串的第几个字符开始删除位置i以及要删除的子串长度j:\\n");
	scanf("%d %d",&i,&j);
	DeleteString(S,i,j);	//删除子串 
	LengthString(S);
	PrintString(S);

运行结果如下:

十一、连接子串

连接子串,也就是将第二个串S2连接到第一个串S1的后,最后形成一个新串S,首先要判断连接成功后的总长度是否预定的存储空间长度,若成功则形成串S,修改串S1的长度并设字符串结束标志;若连接后的串S大于预定的存储空间长度,则多余的部分字符序列将会被舍弃,代码如下:

/*连接子串*/
bool ConnectString(SString &S,SString &S1) 
	int i;
	if(S.length==MAXLEN)	//当串S的长度等于预先设定的存储空间长度MAXLEN则报错 
		return false;
	if(S.length+S1.length<=MAXLEN) 	//连接后,串S的长度小于定的存储空间长度MAXLEN 
		for(i=S.length; i<S.length+S1.length; i++)
			S.ch[i]=S1.ch[i-S.length];
		S.ch[i]='\\0';	//加上字符串结束标志\\0
		S.length=S.length+S1.length;
	 else if(S.length<MAXLEN) 	//连接后,串S的长度大于MAXLEN,但串S1的长度小于MAXLEN,部分字符将被舍弃 
		for(i=S.length; i<MAXLEN; i++)
			S以上是关于数据结构学习笔记——顺序存储结构实现串的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法学习笔记 串,数组和广义表

数据结构学习笔记——顺序存储结构实现栈

数据结构学习笔记——队列的基本知识和顺序存储结构实现队列

数据结构学习笔记——队列的基本知识和顺序存储结构实现队列(顺序队列)

数据结构学习笔记——顺序存储结构实现循环队列

数据结构学习笔记——顺序存储结构实现循环队列