串的定长顺序分配实现

注意事项:

  1. 串是由零个或多个字符组成的有限序列。零个字符的串成为空串。串中任意个字符组成的子序列成为该串的子串。包含子串的串成为主串。
  2. 通常称字符在序列中的序号为该字符在串中的位置。只有当两个串的长度和各个对应位置的字符都相等时,两串才相等。
  3. 串的逻辑结构和线性表相似,但基本操作不同。串多以整体为操作对象,如查找子串、求取子串、在某个位置插入子串及删除。
  4. 串的存储方法有:定长顺序存储、堆分配存储、块链存储
#include<stdio.h>
#include<malloc.h>
#define MAX_LEN 100
 
typedef char SString[MAX_LEN+1];//设定最大值,可定义255以内的数,0号单元存放串的长度。
//和char数组的区别是,第0号存长度,其它序号顺延+1。
int SubString(SString Sub, SString S, int pos, int len);//用Sub返回S中的第pos起len长度的子串
int Index1(SString S, SString T, int pos);//返回子串T在主串S中第pos后的位置,若不在返回0
int StrInsert(SString S, int pos, SString T);//在串S的第pos之前插入串T,成功返回1,不成功为0
int StrDelete(SString S, int pos, int len);//从S串中第pos起删除长度为len的子串
void StrPrint(SString S);
int StrAssign(SString T, char * chars);//将一个char字符串转成SString串
 
int main()
{
	char s, c[MAX_LEN + 1];
	SString t, s1, s2;
	printf("请输入s1:");
	gets(c);
	StrAssign(s1, c);
	SubString(s2, s1, 3, 10);
	int i = Index1(s1, s2, 1);
	printf("s2的子串在s1的%d位后\n", i);
	printf("将s2插入到s1的开头:");
	StrInsert(s1, 1, s2);
	StrPrint(s1);
	printf("将刚才插入的删除后:");
	StrDelete(s1, 1, 10);
	StrPrint(s1);
	return 0;
}
 
int SubString(SString Sub, SString S, int pos, int len)
{
	for (int i = 1; i <= len; i++)
		Sub[i] = S[pos + i - 1];//其中sub[0]用于放置长度
	Sub[0] = len;
	return 1;
}
 
int Index1(SString S, SString T, int pos)//此算法在字符不匹配时,主串指针会完全回溯到初始状态的下一个字符
{
	int i, j;
	if (pos >= 1 && pos <= S[0])
	{
		i = pos;//从主串S的第pos个字符开始和T的第一个字符比较
		j = 1;
		while (i <= S[0] && j <= T[0])
			if (S[i] == T[j])
			{
				i++;
				j++;
			}
			else//当前两字符不相等,两指针后退重新开始分配
			{
				i = i - j + 2;//+2是因为j的初始值是1,而此次指针要回指到开始比较的下一个
				j = 1;
			}
		if (j > T[0])//用于判断是否相等的指针超过了子串的长度,表示主串中存在子串
			return i - T[0];//指向主串中相同子串的首序号
		else
			return 0;
	}
	else
		return 0;
}
 
int StrInsert(SString S, int pos, SString T)
{
	int i;
	if (pos < 1 || pos > S[0] + 1)//之所以是长度+1,因为第0号存储的是长度
		return 0;
	if (S[0] + T[0] <= MAX_LEN)//能够完全插入到主串
	{
		for (i = S[0]; i >= pos; i--)//从最后一个开始每个字符后挪len个位置
			S[i + T[0]] = S[i];
		for (i = pos; i < pos + T[0]; i++)
			S[i] = T[i - pos + 1];
		S[0] += T[0];//更新串S的长度
		return 1;//表示全部插入
	}
	else//部分插入
	{
		for (i = MAX_LEN;i >= pos + T[0]; i--)
			S[i] = S[i - T[0]];//只让出串中现有的空间
		for (i = pos; i < pos + T[0] && i <= MAX_LEN; i++)//此时的插入可能是T的部分插入,也可能将S串一部分覆盖
			S[i] = T[i - pos + 1];
		S[0] = MAX_LEN;
		return 0;//表示部分插入
	}
}
 
int StrDelete(SString S, int pos, int len)
{
	int i;
	if (pos < 1 || pos > S[0] - len + 1 || len < 0)
		return 0;
	for (i = pos + len; i <= S[0]; i++)//对于删除的子串之后的字符
		S[i - len] = S[i];
	S[0] -= len;
	return 1;
}
 
void StrPrint(SString S)
{
	int i;
	for (i = 1; i <= S[0]; i++)
		printf("%c", S[i]);
	printf("%\n");
}
 
int StrAssign(SString S, char * chars)
{
	int i;
	if (strlen(chars) > MAX_LEN)
		return 0;
	else
	{
		S[0] = strlen(chars);
		for (i = 1; i <= S[0]; i++)
			S[i] = *(chars + i - 1);
		return 1;
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值