数据结构笔记(十二)-- 定长顺序结构的实现

定长顺序结构的实现

一、定长顺序结构的概述

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

二、串的定长顺序存储表示

# define MAXSTRLEN 40//用户可以在255以内定义最大串长
typedef unsigned char SString[MAXSTRLEN + 1];//0号单元存放串的长度

串的实际长度可在这个预定义长度范围内随意,超出预定义长度的串则会被舍去,这称之为“截断”。

三、串的两种表示方法

1、0号单元存放串的长度

如上述定义的那样,一下标为0的数组分量存放串的实际长度。

2、串值后加"\0"

即在串值后加入一个不计入串长的结束标记字符。此时串长是一个隐含值,不变域操作。

四、串的操作

//1、生成一个其值等于chars的字符串T
bool StrAssign(SString T, char *chars);
//2、由串T复制得串S
void StrCopy(SString S, SString T);
//3、若S为空串,则返回true,否则返回false
bool StrEmpty(SString S);
//4、字符串长短比较,返回S长度-T长度
int StrCompare(SString S, SString T);
//5、返回串S的元素个数
int StrLength(SString S);
//6、显示串的值
void Strshow(SString S);
//7、串的拼接 S1后接S2,结果在T中。
bool StrConcat1(SString T, SString S1, SString S2);
//8、串的拼接 S1后接S2,结果放在S1中
bool StrConcat2(SString S1, SString S2);
//9、用Sub返回串S的第pos个字符起(包括pos位置处的字符)长度为len的子串。
bool SubString(SString Sub, SString S, int pos, int len);
//10、清空串
void ClearString(SString S);
//11、 返回子串T在主串S中的位置。若不存在,则函数值为0,其中,T非空。
int Index1(SString S, SString T);
//12、 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。
int Index2(SString S, SString T, int pos);
//13、在串S的第pos个字符之前插入串T。完全插入返回true,部分插入返回false
bool StrInsert(SString S, int pos, SString T);
//14、从串S中删除第pos个字符起长度为len的子串
bool StrDelete(SString S, int pos, int len);

五、串操作的实现

1、生成一个其值等于chars的字符串T

在这里插入图片描述

bool StrAssign(SString T, char *chars)
{
	int i;
	if (strlen(chars) > MAX_STR_LEN)//chars 的长度大于最大长度,返回false
		return false;
	else
	{
		T[0] = strlen(chars); // 0号单元存放串的长度
		for (i = 1; i <= T[0]; i++)//从1号单元开始复制串的内容
		{
			
			T[i] = *(chars + i - 1);//等价于T[i] = chars[i-1];	
		}
		return true;
	}
}

2、由串S复制得串T

在这里插入图片描述

void StrCopy(SString T, SString S)
{ 
	int i;
	for (i = 0; i <= S[0]; i++)
		T[i] = S[i];
}

3、若S为空串,则返回true,否则返回false

//3、若S为空串,则返回true,否则返回false
bool StrEmpty(SString S)
{
	if (S[0] == 0)
		return true;
	else
		return false;
}

4、字符串长短比较,返回S长度-T长度

int StrCompare(SString S, SString T)
{// 初始条件:串S和T存在。
 //操作结果:若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
	int i;
	for (i = 1; i <= S[0] && i <= T[0]; ++i)
		if (S[i] != T[i])
			return S[i] - T[i];
	return S[0] - T[0];
}

5、返回串S的元素个数

int StrLength(SString S)
{ 
	return S[0];
}

6、显示串的值

void Strshow(SString S)
{
	int i;
	for (i = 1; i <= S[0]; i++)//从1号单元开始逐单元输出串中的字符
	{
		printf("  %c", S[i]);
	}
	printf("\n");
}

7、串的拼接 S1后接S2,结果放在T中

当S1和S2的长度加在一起超出MAX_STR_LEN时,S2会被截断
在这里插入图片描述

bool StrConcat1(SString T, SString S1, SString S2) 
{ // 用T返回S1和S2联接而成的新串。若未截断,则返回true,否则false
	int i;
	if (S1[0] + S2[0] <= MAX_STR_LEN)
	{ // 未截断
		for (i = 1; i <= S1[0]; i++)//先放S[1]到T中
			T[i] = S1[i];
		for (i = 1; i <= S2[0]; i++)//接着放S[2]到T中
			T[S1[0] + i] = S2[i];
		T[0] = S1[0] + S2[0];
		return true;
	}
	else
	{ // 截断S2
		for (i = 1; i <= S1[0]; i++)//先放S[1]到T中
			T[i] = S1[i];
		for (i = 1; i <= MAX_STR_LEN - S1[0]; i++)//关键,若第一个串长度超过MAX_STR_LEN 则条件不成立,这里循环的次数为,S1剩余空间单位数
			T[S1[0] + i] = S2[i];
		T[0] = MAX_STR_LEN;
		return false;
	}
}

8、串的拼接 S1后接S2,结果放在S1中

在这里插入图片描述

bool StrConcat2(SString S1, SString S2)
{ // 用T返回S1和S2联接而成的新串。若未截断,则返回true,否则false
	int i = 1;
	int lens1 = S1[0];//保存S1的长度
	while (i <= (MAX_STR_LEN - S1[0]) && i<= S2[0])//i小于等于除去S1长度剩余的长度&&i小于S2的长度
	{
		S1[S1[0] + i] = S2[i];//逐字符赋值
		i++;
	}
	S1[0] = S1[0] + i - 1;//更新S1长度
	if ((lens1 + S2[0]) <= MAX_STR_LEN)//判断有没有截断
		return true;
	else
		return false;	
}

9、用Sub返回串S的第pos个字符起(包括pos位置处的字符)长度为len的子串。

在这里插入图片描述

bool SubString(SString Sub, SString S, int pos, int len)
{ 
	int i;
	if (pos<1 || pos>S[0] || len<0 || len>S[0] - pos + 1)//排除pos值不在S长度范围内的值和len值+pos值超出S长度
		return false;
	for (i = 1; i <= len; i++)
		Sub[i] = S[pos + i - 1];//包括pos位置处的字符
	Sub[0] = len;
	return true;
}

10、清空串

void ClearString(SString S)
{ // 初始条件:串S存在。
  //操作结果:将S清为空串
	S[0] = 0; // 令串长为零
}

11、 返回子串T在主串S中的位置。若不存在,则函数值为0,其中,T非空

在这里插入图片描述

int Index1(SString S, SString T)
{
	int i = 1, j = 1;
	for ( i = 1; i <=S[0]; i++)//循环主串
	{
		if (S[i]==T[1])//如果在主串中找到一个与子串的第一个字符相等的字符时
		{
			int cont = 1;//计数变量
			for ( j = 1; j <=T[0]; j++)//遍历子串
			{
				if (T[j + 1] != S[i + j])//在遍历T[0]时如果有不一致时退出遍历
				{ 
					break;
				}
				else//否则计数
				{
					cont++;
					if (cont == T[0])//当有T[0]个字符相同时则找到子串位置
						return i;
				}									
			}			
		}
	continue;	
	}
	return 0;//不存在时
}

12、 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。

在这里插入图片描述

int Index2(SString S, SString T, int pos)
{ 
	int i, j;
	if (1 <= pos && pos <= S[0])
	{
		i = pos;//从主串的第pos个字符开始和子串的第一个字符比较
		j = 1;
		while (i <= S[0] && j <= T[0])
		{ 
			if (S[i] == T[j]) // 若第一个字符比较后相等则继续比较后继字符
			{
				++i;
				++j;
			}
			else //若第一个字符不叫后不相等则后移一个位置重新开始匹配
			{
				i = i - j + 2;
				j = 1;
			}
		}
		if (j > T[0])//条件成立表示子串中的所有字符都能匹配相等,即主串中包含子串
			return i - T[0];
		else
			return 0;
	}
	else
		return 0;
}

13、在串S的第pos个字符之前插入串T。完全插入返回true,部分插入返回false在这里插入图片描述

bool StrInsert(SString S, int pos, SString T)
{ // 初始条件:串S和T存在,1≤pos≤StrLength(S)+1
  // 操作结果:在串S的第pos个字符之前插入串T,第pos个位置插入T[1]。完全插入返回true,部分插入返回false
	int i;
	if (pos<1 || pos>S[0] + 1)//插入位置不在S长度范围之内
		return false;
	if (S[0] + T[0] <= MAX_STR_LEN)
	{ // 完全插入
		for (i = S[0]; i >= pos; i--)//pos之后的元素后移T[0]个长度
			S[i + T[0]] = S[i];
		for (i = pos; i < pos + T[0]; i++)//插入
			S[i] = T[i - pos + 1];
		S[0] += T[0];//更新长度
		return true;
	}
	else
	{ // 部分插入
		for (i = MAX_STR_LEN; i >= pos + T[0]; i--)//移动串S中位于pos之后仍在串内的字符,因为(S[0] + T[0] > MAX_STR_LEN)所S串插入T后必满, pos + T[0]是插入元素和pos及pos之前元素所占位置
			S[i] = S[i - T[0]];
		for (i = pos; i < pos + T[0] && i <= MAX_STR_LEN; i++)
			S[i] = T[i - pos + 1];
		S[0] = MAX_STR_LEN;//S的长度为最大
		return false;//部分插入
	}
}

14、从串S中删除第pos个字符起长度为len的子串

bool StrDelete(SString S, int pos, int len)
{ // 初始条件:串S存在,1≤pos≤StrLength(S)-len+1
  // 操作结果:从串S中删除第pos个字符起长度为len的子串
	int i;
	if (pos<1 || pos>S[0] - len + 1 || len < 0)//pos和len的值超出范围
		return false;
	for (i = pos + len; i <= S[0]; i++)//循环删除子串后的所有字符
		S[i - len] = S[i];//向前移动len个位置
	S[0] -= len;//更新串S的长度
	return  true;
}

最后给出完整代码

// 串的定长顺序存储结构.cpp
#include<string.h>
#include<malloc.h> // malloc()等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()

#define MAX_STR_LEN 40 // 用户可在255(1个字节)以内定义最大串长
typedef char SString[MAX_STR_LEN + 1]; // 0号单元存放串的长度
 // SString是数组,故不需引用类型


//1、生成一个其值等于chars的字符串T
bool StrAssign(SString T, char *chars);
//2、由串T复制得串S
void StrCopy(SString S, SString T);
//3、若S为空串,则返回true,否则返回false
bool StrEmpty(SString S);
//4、字符串长短比较,返回S长度-T长度
int StrCompare(SString S, SString T);
//5、返回串S的元素个数
int StrLength(SString S);
//6、显示串的值
void Strshow(SString S);
//7、串的拼接 S1后接S2,结果在T中。
bool StrConcat1(SString T, SString S1, SString S2);
//8、串的拼接 S1后接S2,结果放在S1中
bool StrConcat2(SString S1, SString S2);
//9、用Sub返回串S的第pos个字符起(包括pos位置处的字符)长度为len的子串。
bool SubString(SString Sub, SString S, int pos, int len);
//10、清空串
void ClearString(SString S);
//11、 返回子串T在主串S中的位置。若不存在,则函数值为0,其中,T非空。
int Index1(SString S, SString T);
//12、 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。
int Index2(SString S, SString T, int pos);
//13、在串S的第pos个字符之前插入串T。完全插入返回true,部分插入返回false
bool StrInsert(SString S, int pos, SString T);
//14、从串S中删除第pos个字符起长度为len的子串
bool StrDelete(SString S, int pos, int len);

int  main()
{
	char  c[MAX_STR_LEN + 1];
	SString T;
	printf("请输入串T: ");
	gets_s(c);//接收字符串
	printf("输入的字符串为 %s\n", c);
	printf("输入的字符串长度为 %d\n", strlen(c));
	
	if (!StrAssign(T, c))
	{
		printf("串长超过MAX_STR_LEN(=%d)\n", MAX_STR_LEN);
		exit(0);
	}
	Strshow(T);
	printf("T长度为 %d\n", StrLength(T));
	///
	SString S;
	StrCopy(S, T);
	Strshow(S);
	///
	if (StrEmpty(S))
	{
		printf("串S为空!\n");
	}
	else
	{
		printf("串S不为空!\n");
	}
	printf("比较S和T的长度结果 %d\n", StrCompare(S, T));


	SString S1, S2;
	printf("请输入串s1: ");
	gets_s(c);//接收字符串
	printf("输入的字符串S1为 %s\n", c);
	printf("输入的字符串S1长度为 %d\n", strlen(c));
	StrAssign(S1, c);
	printf("请输入串s2: ");
	gets_s(c);//接收字符串
	StrAssign(S2, c);
	printf("输入的字符串S2为 %s\n", c);
	printf("输入的字符串S2长度为 %d\n", strlen(c));
	StrConcat1(T, S1, S2);
	Strshow(T);
	StrConcat2(S1, S2);
	Strshow(S1);
	printf("字符串S1长度为 %d\n", S1[0]);
	printf("T在S1中的位置为 %d\n",Index1(S1, S2));
	int pos = 3, len = 2;
	printf("T在S1中的位置为 %d\n",Index2(S1, S2,pos));
	StrInsert(S1, pos, T);
	Strshow(S1);
	StrDelete(S1, pos,len);
	Strshow(S1);



	

	return 0;
}

//1、生成一个其值等于chars的字符串T
bool StrAssign(SString T, char *chars)
{
	int i;
	if (strlen(chars) > MAX_STR_LEN)//chars 的长度大于最大长度,返回false
		return false;
	else
	{
		T[0] = strlen(chars); // 0号单元存放串的长度
		for (i = 1; i <= T[0]; i++)//从1号单元开始复制串的内容
		{
			
			T[i] = *(chars + i - 1);//等价于T[i] = chars[i-1];	
		}
		return true;
	}
}
//2、由串T复制得串S
void StrCopy(SString S, SString T )
{ 
	int i;
	for (i = 0; i <= T[0]; i++)
		S[i] = T[i];
}

//3、若S为空串,则返回true,否则返回false
bool StrEmpty(SString S)
{
	if (S[0] == 0)
		return true;
	else
		return false;
}
//4、字符串长短比较,返回S长度-T长度
int StrCompare(SString S, SString T)
{// 初始条件:串S和T存在。
 //操作结果:若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
	int i;
	for (i = 1; i <= S[0] && i <= T[0]; ++i)
		if (S[i] != T[i])
			return S[i] - T[i];
	return S[0] - T[0];
}
//5、返回串S的元素个数
int StrLength(SString S)
{ 
	return S[0];
}

//6、显示串的值
void Strshow(SString S)
{
	int i;
	for (i = 1; i <= S[0]; i++)//从1号单元开始逐单元输出串中的字符
	{
		printf("  %c", S[i]);
	}
	printf("\n");
}

//7、串的拼接 S1后接S2,结果放在T中
bool StrConcat1(SString T, SString S1, SString S2) 
{ // 用T返回S1和S2联接而成的新串。若未截断,则返回true,否则false
	int i;
	if (S1[0] + S2[0] <= MAX_STR_LEN)
	{ // 未截断
		for (i = 1; i <= S1[0]; i++)//先放S[1]到T中
			T[i] = S1[i];
		for (i = 1; i <= S2[0]; i++)//接着放S[2]到T中
			T[S1[0] + i] = S2[i];
		T[0] = S1[0] + S2[0];
		return true;
	}
	else
	{ // 截断S2
		for (i = 1; i <= S1[0]; i++)//先放S[1]到T中
			T[i] = S1[i];
		for (i = 1; i <= MAX_STR_LEN - S1[0]; i++)//关键,若第一个串长度超过MAX_STR_LEN 则条件不成立
			T[S1[0] + i] = S2[i];
		T[0] = MAX_STR_LEN;
		return false;
	}
}

//8、串的拼接 S1后接S2,结果放在S1中
bool StrConcat2(SString S1, SString S2)
{ // 用T返回S1和S2联接而成的新串。若未截断,则返回true,否则false
	int i = 1;
	int lens1 = S1[0];//保存S1的长度
	while (i <= (MAX_STR_LEN - S1[0]) && i<= S2[0])//i小于等于除去S1长度剩余的长度&&i小于S2的长度
	{
		S1[S1[0] + i] = S2[i];//逐字符赋值
		i++;
	}
	S1[0] = S1[0] + i - 1;//更新S1长度
	if ((lens1 + S2[0]) <= MAX_STR_LEN)//判断有没有截断
		return true;
	else
		return false;	
}


//9、用Sub返回串S的第pos个字符起(包括pos位置处的字符)长度为len的子串。
bool SubString(SString Sub, SString S, int pos, int len)
{ 
	int i;
	if (pos<1 || pos>S[0] || len<0 || len>S[0] - pos + 1)//排除pos值不在S长度范围内的值和len值+pos值超出S长度
		return false;
	for (i = 1; i <= len; i++)
		Sub[i] = S[pos + i - 1];//包括pos位置处的字符
	Sub[0] = len;
	return true;
}
//10、清空串
void ClearString(SString S)
{ // 初始条件:串S存在。
  //操作结果:将S清为空串
	S[0] = 0; // 令串长为零
}

//11、 返回子串T在主串S中的位置。若不存在,则函数值为0,其中,T非空。
int Index1(SString S, SString T)
{
	int i = 1, j = 1;
	for ( i = 1; i <=S[0]; i++)//循环主串
	{
		if (S[i]==T[1])//如果在主串中找到一个与子串的第一个字符相等的字符时
		{
			int cont = 1;//计数变量
			for ( j = 1; j <=T[0]; j++)//遍历子串
			{
				if (T[j + 1] != S[i + j])//在遍历T[0]时如果有不一致时退出遍历
				{ 
					break;
				}
				else//否则计数
				{
					cont++;
					if (cont == T[0])//当有T[0]个字符相同时则找到子串位置
						return i;
				}									
			}			
		}
	continue;	
	}
	return 0;//不存在时
}


//12、 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。
int Index2(SString S, SString T, int pos)
{ 
	int i, j;
	if (1 <= pos && pos <= S[0])
	{
		i = pos;//从主串的第pos个字符开始和子串的第一个字符比较
		j = 1;
		while (i <= S[0] && j <= T[0])
		{ 
			if (S[i] == T[j]) // 继续比较后继字符
			{
				++i;
				++j;
			}
			else // 指针后退重新开始匹配
			{
				i = i - j + 2;
				j = 1;
			}
		}
		if (j > T[0])
			return i - T[0];
		else
			return 0;
	}
	else
		return 0;
}
//13、在串S的第pos个字符之前插入串T。完全插入返回true,部分插入返回false
bool StrInsert(SString S, int pos, SString T)
{ // 初始条件:串S和T存在,1≤pos≤StrLength(S)+1
  // 操作结果:在串S的第pos个字符之前插入串T,第pos个位置插入T[1]。完全插入返回true,部分插入返回false
	int i;
	if (pos<1 || pos>S[0] + 1)//插入位置不在S长度范围之内
		return false;
	if (S[0] + T[0] <= MAX_STR_LEN)
	{ // 完全插入
		for (i = S[0]; i >= pos; i--)//pos之后的元素后移T[0]个长度
			S[i + T[0]] = S[i];
		for (i = pos; i < pos + T[0]; i++)//插入
			S[i] = T[i - pos + 1];
		S[0] += T[0];//更新长度
		return true;
	}
	else
	{ // 部分插入
		for (i = MAX_STR_LEN; i >= pos + T[0]; i--)//移动串S中位于pos之后仍在串内的字符,因为(S[0] + T[0] > MAX_STR_LEN)所S串插入T后必满, pos + T[0]是插入元素和pos及pos之前元素所占位置
			S[i] = S[i - T[0]];
		for (i = pos; i < pos + T[0] && i <= MAX_STR_LEN; i++)
			S[i] = T[i - pos + 1];
		S[0] = MAX_STR_LEN;//S的长度为最大
		return false;//部分插入
	}
}
//14、从串S中删除第pos个字符起长度为len的子串
bool StrDelete(SString S, int pos, int len)
{ // 初始条件:串S存在,1≤pos≤StrLength(S)-len+1
  // 操作结果:从串S中删除第pos个字符起长度为len的子串
	int i;
	if (pos<1 || pos>S[0] - len + 1 || len < 0)//pos和len的值超出范围
		return false;
	for (i = pos + len; i <= S[0]; i++)//循环删除子串后的所有字符
		S[i - len] = S[i];//向前移动len个位置
	S[0] -= len;//更新串S的长度
	return  true;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值