串的堆分配实现

注意事项:

  1. 在串的顺序存取中,一旦操作的串序列长度超过上界时,会采用截尾法处理,克服这个弊端可以使用动态分配串值得存储空间。
  2. 堆分配——也是以一组地址连续的存储单元存放串值字符序列,但他们的存储空间是在程序运行过程中动态分配而得。
  3. 一般对串操作时,多使用堆分配存储方式。
#include<stdio.h>
#include<string.h>
#include<malloc.h>
 
typedef struct //heap堆
{
	char *ch;
	int length;
}HS, *HString;//这里为了C语言方便,直接设定指向结构的指针,如使用C++这里可以直接设结构类型
void InitString(HString S);
void StrAssign(HString T, char * chars);//将串常量chars赋值给串T
void StrCopy(HString T, HString S);     //将串S赋值给串T
int StrCompare(HString S, HString T);    //若S>T返回>0,如S=T返回0,否则返回<0
void Concat(HString T, HString s1, HString s2);//由T返回s1和s2连接而成的新串
int SubString(HString sub, HString S, int pos, int len);//用sub返回串S中自pos起len长度的子串
int StrInsert(HString S, int pos, HString T);
int StrDelete(HString S, int pos, int len);
void StrPrint(HString S);
 
int main()
{
	int i;
	char c, *p = "God bye!", *q = "God luck!";
	HString T = (HString)malloc(sizeof(HS));
	HString S = (HString)malloc(sizeof(HS));
	HString R = (HString)malloc(sizeof(HS));
	InitString(T);
	InitString(S);
	InitString(R);
	StrAssign(T, p);
	printf("串t为:");
	StrPrint(T);
	StrAssign(S, q);
	printf("串s为:");
	StrPrint(S);
	i = StrCompare(S, T);
	if (i < 0)
		c = '<';
	else if (i > 0)
		c = '>';
	else
		c = '=';
	printf("串s %c 串t", c);
	Concat(R, S, T);
	printf("串t连接s产生的串r为:");
	StrPrint(R);
	return 0;
}
 
void InitString(HString S)
{
	S->length = 0;
	S->ch = NULL;
}
void StrAssign(HString T, char *chars)
{
	int i, j;
	if (T->ch)
		free(T->ch);//若原本有值,将其空间释放
	i = strlen(chars);
	if (!i)
		InitString(T);
	else
	{
		T->ch = (char*)malloc(i * sizeof(char));//根据chars的长度为其分配空间
		for (j = 0; j < i; j++)
			T->ch[j] = chars[j];
		T->length = i;
	}
}
void StrCopy(HString T, HString S)
{
	int i;
	if (T->ch)
		free(T->ch);
	T->ch = (char*)malloc(S->length * sizeof(char));
	for (i = 0; i < S->length; i++)
		T->ch[i] = S->ch[i];
	T->length = S->length;
}
 
int StrCompare(HString S, HString T)
{
	int i;
	for (i = 0; i < S->length && i < T->length; i++)
		if (S->ch[i] != T->ch[i])
			return S->ch[i] - T->ch[i];
	return S->length - T->length;//如果某一个串长度读完了,字符串还相等,返回两者的长度差。
}
void Concat(HString T, HString S1, HString S2)
{
	int i;
	if (T->ch)
		T->ch = NULL;
	T->length = S1->length + S2->length;
	T->ch = (char*)malloc(T->length * sizeof(char));
	for (i = 0; i < S1->length; i++)
		T->ch[i] = S1->ch[i];
	for (i = 0; i < S2->length; i++)
		T->ch[i + S1->length] = S2->ch[i];//从第一个串长度之后开始,串长代表的位置正好是第一个串结束的下一个
}
int SubString(HString Sub, HString S, int pos, int len)//pos是指第pos个字符后,从1开始的。
{
	int i;
	if (pos > S->length || pos < 1 || len <0 || len >= S->length - pos)
		return 0;
	if (Sub->ch)
		Sub->ch = NULL;
	if (!len)
		InitString(Sub);
	else
	{
		Sub->ch = (char*)malloc(len * sizeof(char));
		for (i = 0; i < len; i++)
			Sub->ch[i] = S->ch[i];
		Sub->length = len;
	}
}
 
int StrInsert(HString S, int pos, HString T)
{
	int i;
	if (pos < 1 || pos > S->length + 1)
		return 0;
	if (T->length)
	{
		S->ch = (char*)realloc(S->ch, (S->length + T->length) * sizeof(char));
		for (i = S->length - 1; i >= pos - 1; --i)//让串S腾出位置
			S->ch[i + T->length] = S->ch[i];//在腾位置的时候一般都是从最后面开始往前
		for (i = 0; i < T->length; i++)
			S->ch[pos + i - 1] = T->ch[i];
		S->length += T->length;
	}
}
int StrDelete(HString S, int pos, int len)
{
	int i;
	if (S->length <= pos + len)
		return 0;
	for (i = pos - 1; i <= S->length - len; i++)
		S->ch[i] = S->ch[i + len];
	S->length -= len;
	S->ch = (char*)realloc(S->ch, S->length * sizeof(char));//先将pos+len后面的覆盖到pos后,然后在给串重新分空间
	return 1;
}
void StrPrint(HString S)
{
	int i;
	for (i = 0; i < S->length; i++)
		printf("%c", S->ch[i]);
	printf("\n");
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是C语言实现分配的代码示例: ```c // 结构 typedef struct HString { char *ch; // 指向字符所在空间首地址 int length; // 记录字符长度 } HString; // 初始化 void InitString(HString *S) { S->ch = NULL; S->length = 0; } // 生成一个等于常量T的S void StrAssign(HString *S, char *T) { int len = strlen(T); if (len == 0) { S->ch = NULL; S->length = 0; } else { S->ch = (char *)malloc(sizeof(char) * len); assert(S->ch != NULL); for (int i = 0; i < len; ++i) { S->ch[i] = T[i]; } S->length = len; } } // 销毁 void DestroyString(HString *S) { if (S->ch != NULL) { free(S->ch); S->ch = NULL; } S->length = 0; } // 复制 void StrCopy(HString *S, HString *T) { int len = T->length; if (S->ch != NULL) { free(S->ch); } S->ch = (char *)malloc(sizeof(char) * len); assert(S->ch != NULL); for (int i = 0; i < len; ++i) { S->ch[i] = T->ch[i]; } S->length = len; } // 比较 int StrCompare(HString *S, HString *T) { for (int i = 0; i < S->length && i < T->length; ++i) { if (S->ch[i] != T->ch[i]) { return S->ch[i] - T->ch[i]; } } return S->length - T->length; } // 求子 void SubString(HString *Sub, HString *S, int pos, int len) { if (pos < 1 || pos > S->length || len < 0 || pos + len - 1 > S->length) { printf("Error: invalid position or length.\n"); exit(1); } if (Sub->ch != NULL) { free(Sub->ch); } if (len == 0) { Sub->ch = NULL; Sub->length = 0; } else { Sub->ch = (char *)malloc(sizeof(char) * len); assert(Sub->ch != NULL); for (int i = 0; i < len; ++i) { Sub->ch[i] = S->ch[pos + i - 1]; } Sub->length = len; } } // 插入 void StrInsert(HString *S, int pos, HString *T) { if (pos < 1 || pos > S->length + 1) { printf("Error: invalid position.\n"); exit(1); } int len = T->length; S->ch = (char *)realloc(S->ch, sizeof(char) * (S->length + len)); assert(S->ch != NULL); for (int i = S->length - 1; i >= pos - 1; --i) { S->ch[i + len] = S->ch[i]; } for (int i = 0; i < len; ++i) { S->ch[pos + i - 1] = T->ch[i]; } S->length += len; } // 删除 void StrDelete(HString *S, int pos, int len) { if (pos < 1 || pos > S->length || len < 0 || pos + len - 1 > S->length) { printf("Error: invalid position or length.\n"); exit(1); } for (int i = pos - 1; i < S->length - len; ++i) { S->ch[i] = S->ch[i + len]; } S->length -= len; S->ch = (char *)realloc(S->ch, sizeof(char) * S->length); assert(S->ch != NULL); } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值