什么是串,串的表示和实现串的顺序存储和单链存储

一. 串类型的定义

字符串是n(n>=0)个字符的有限序列,记作:  S=“C1C2C3...Cn”
其中:

S是串名字;
“C1C2C3…Cn” 是串值;
Ci 是串中字符
n 是串的长度;
n=0 称为空串


由一个或多个空白符组成的串称为空白串;
串中任意个连续字符组成的子序列称为该串的子串;
包含子串的串相应地称为主串;
通常将子串在主串中首次出现时,该子串首字符对应的主串中的序号,定义为子串在主串中的位置。


例如,设 A = “This is a string” , B = “is” 则B是A的子串,A为主串。B在A中出现了两次,首次出现所对应的主串的位置是2(从0开始)。因此,称B在A中的位置为2.
空串是任意串的子串,任意串是其自身的子串。

二. 串的表示和实现

除C语言提供的字符串库函数外,可以自定义字符串。
适用于自定义字符串数据类型的有三种存储表示:

  • 定长顺序存储表示
  • 堆分配存储表示
  • 块链存储表示

 定长顺序存储表示

顺序串:使用静态分配的字符数组存储字符串中的字符序列。
字符数组的长度预先用MAXSTRLEN确定,一旦空间存满,不能扩充。
有两种实现定长顺序存储表示:
字符串存放于字符数组的0 ~ MAXSTRLEN-1单元,另外用整数length记录串中实际存放的字符个数。
字符串存放于字符数组的1 ~ MAXSTRLEN-1单元,用0号单元记录串中实际存放的字符个数。
定长存储表示的定义如下:

#define MAXSTRLEN 256        //顺序串的预设长度 
typedef struct{			    //顺序串的定义 
   char SString[MAXSTRLEN] //存储字符数组 
   int length;				//串中实际字符个数 
}SqString;

堆分配存储表示

  • 堆式串:字符数组的存储空间是通过malloc()函数动态分配的。
  • 串的最大空间数MAXSTRLEN和串中实际字符个数length保存在串的定义中。
  • 可以根据需要,随时改变字符数组的大小。
  • 堆分配存储表示的定义如下:
    #define MAXSTRLEN 256        //顺序串的预设长度 
    typedef struct{			  
       char *ch;                              //存储字符数组
       int maxSize;						//串数组的最大长度 
       int length;				           //串的当前长度 
    }HString;
    

块链存储表示

  • 使用单链表作为字符串的存储表示,此即字符串的链接存储表示。
  • 链表的每个结点可以存储1个字符,称其块的大小为1,也可以存储n个字符,称其块的大小为n。
  • 定义存储密度为:

在这里插入图片描述

 存储密度越高,存储利用率越高。
块链存储表示一般带头结点,设置头,尾指针。

  • 块链存储表示的定义如下:
#define blockSize 4         //由使用者定义的结点大小
typedef struct bloak{       
   char ch[blockSize];
   struct block *next;    //头结点
}Chunk; 
typedef struct{			    
   Chunk *first, *last;    //链表的头指针和尾指针 
   int length;				//串的当前长度 
}LString;

 串的相关算法(堆存储部分操作的实现)

初始化空串算法

void initString(Hstring &S)
{
	S.ch = (char *)malloc(MAXSTRLEN*sizeof(char));  //分配字符数组空间 
	if(S.ch == NULL)
		exit(1);				//判断分配是否成功 
	S.ch[0] = '\0';				//置空串 
	S.maxSize = MAXSTRLEN;		//置串的最大字符数 
	S.length = 0;				//实际字符数置0 
}

提取子串算法

代码实现: 

HString subString(HString &s, int pos, int len)
{
	HString tmp;
	//创建子串空间 
	tmp.ch = (char *)malloc(MAXSTRLEN*sizeof(char));
	tmp.maxSize = MAXSTRLEN;
	if(pos<0 || len<0 || pos+len-1 >= s.maxSize) 
	{  //参数不合理,返回空串
		tmp.length = 0;
		tmp.ch[0] = '\0'; 
	}
	else 
	{
		if(pos+len-1 >= s.length)
			len = s.length-pos;
		for(int i=0, j=pos; i<len; i++, j++)
			tmp.ch[i] = s.ch[i];   //复制子串的字符 
		tmp.length = len;
		tmp.ch[len] = '\0';
	}
	return tmp;						//返回复制的子串 
}

串的连接算法

void concat(HeapString &s, Heapstring &t)
{
	if(s.length + t.length <= s.maxSize) 
	{  //原空间可容纳连接后的串 
		for(int i=0; i<t.n; i++)
			s.ch[s.length+i] = t.ch[i];  //串t复制到串s后 
		s.length = s.length + t.length;
		s.ch[s.length]= '\0'; 
	}
	else //原空间容不下连接后的串 
	{
		char *tmp = s.ch;
		s.maxSize = s.length + t.length;
		s.ch = (char *)malloc((s.maxSize+1)*sizeof(char)); 
		strcpy(s.ch, tmp);  //复制原串s数组 
		strcat(s.ch, t.ch); //连接串t数组 
		s.length = s.length + t.length;
		free(tmp);
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值