串的堆式存储结构

串的堆式存储结构

在C和C++语言中 ,提供一个称之为“堆”的共享空间,可以在程序运行过程中,系统利用函数malloc( )和free( )动态地申请或释放一块连续空间。

由于在C和C++语言中可以用指针对数组进行访问和操作,在串的存储和操作上也可以充分利用上述特性。

串的堆式存储结构类似于线性表的顺序存储结构,以一组地址连续的存储单元存放串值字符序列,其存储空间是在程序执行过程中动态分配的,而不是静态分配的。

串的堆式存储结构定义

Typedef struct 
{  char *ch;   //指针域,指向存放串值的存储空间基址
   int length;  // 整型域:存放串长 
}HString;

说明:在这种存储结构下,由于串仍然是以数组存储的字符序列表示,因此此类串的操作是先为新生成的串分配一个存储空间,然后进行“字符序列的复制”。例如,如串插入操作StrInsert(S,pos ,T)(将串T插入到串S的第pos字符之前)的算法是,为串S重新分配大小等于串S和串T长度之和的存储空间,然后进行将S和T串值复制到新分配存储空间中。

串的一系列实现

/*
 串的堆式存储表示
 */
#include<stdio.h>
#include<stdlib.h>
#define OVERFLOW   -2//堆溢出
#define OK          1//函数执行成功
#define ERROR      -1//函数执行失败
typedef int datatype;
typedef struct {
	char* ch; //指针域,指向存放串值的存储空间基址
	int len; // 整型域:存放串长
} HString;
//初始化一个空串
datatype InitHString(HString* s) {
	s->ch = (char*) malloc(sizeof(char));
	if (NULL == s->ch)
		return OVERFLOW;
	s->ch = NULL;
	s->len = 0;
	return OK;
}
//为串赋值
datatype assigment_string(HString* s, const char* str) {
	if (s->ch)
		free(s->ch);
	int length = 0, i;
	while (str[length] != '\0')
		length++;
	s->ch = (char*) malloc(length * sizeof(char));
	if (!s->ch)
		return OVERFLOW;
	for (i = 0; i < length; i++)
		*(s->ch + i) = *(str + i);
	s->len = length;
	*(s->ch + s->len) = '\0';
	return OK;
}
//打印
void PrintString(const HString* s) {
	int i = 0;
	while (*(s->ch + i) != '\0') {
		printf("%c", *(s->ch + i));
		i++;
	}
	printf("\n");
}
//求串的长度
datatype GetLength(const HString* s) {
	int len = 0;
	while (*(s->ch + len) != '\0')
		len++;
	return len;
}
//查找某个字符的位置,返回位序
datatype HSLocal(const HString* s, char c) {
	int i;
	for (i = 0; i < s->len; i++) {
		if (c == *(s->ch + i))
			return i + 1;
	}
	return -1;
}
//串的连接
datatype HSCat(HString* s, const HString* t) {
	int i = 0;
	char* temp = (char*) malloc((s->len + t->len) * sizeof(char));
	if (!temp)
		return OVERFLOW;
	for (i = 0; i < s->len; i++)
		*(temp + i) = *(s->ch + i);
	free(s->ch); //释放防止内存泄漏
	for (i = 0; i < t->len; i++)
		*(temp + i + s->len) = *(t->ch + i);
	s->len += t->len;
	s->ch = temp; //使s->ch重新指向temp
	*(s->ch + s->len) = '\0';
	return OK;
}
datatype HSCopy(HString* to, const HString* from) {
	//如果目标串不为空则清空	if(to->ch)
	{
		free(to->ch);
		to->ch = NULL;
		to->len = 0;
	}
	int i = 0;
	to->len = from->len;
	to->ch = (char*) malloc(from->len * sizeof(char));
	if (!to->ch)
		return OVERFLOW;
	for (i = 0; i < from->len; i++)
		*(to->ch + i) = *(from->ch + i);
	*(to->ch + to->len) = '\0';
	return OK;

}
//在串s的pos位置处插入串t
datatype HSInsert(HString* s, const HString *t, int pos) {
	if (pos < 0 || pos > s->len)
		return ERROR;
	else {
		s->ch = (char*) realloc(s->ch, (s->len + t->len) * sizeof(char));
		int i, j = 1;
		//后移
		for (i = s->len + t->len - 1; i >= pos + t->len; i--) {
			*(s->ch + i) = *(s->ch + (s->len - j));
			j++;
		}
		//insert  
		for (i = 0; i < t->len; i++)
			*(s->ch + i + pos) = *(t->ch + i);
	}
	s->len += t->len;
	*(s->ch + s->len) = '\0';
	return OK;
}
//在串s的index位置删除长度为x个字符
datatype HSdel(HString* s, int index, int x) {
	// index value invalid
	if (index < 0 || index > s->len)
		return ERROR;
	//  if x+index> s->len
	if ((index + x) >= s->len)
		s->len = index;
	else {
		int i;
		for (i = index; i < s->len; i++) {
			*(s->ch + i) = *(s->ch + i + x);
		}
		s->len -= x;
	}
	*(s->ch + s->len) = '\0';
	return OK;
}
//串比较
datatype HScomp(const HString* s1, const HString* s2) {
	int i = 0;
	for (i = 0; i < s1->len && i < s2->len; i++) {
		if (*(s1->ch + i) != *(s2->ch + i))
			return *(s1->ch + i) - *(s2->ch + i);
	}
	if (i < s1.len) {
		return 1;
	} else if (i < s2.len) {
		return -1;
	} else {
		return 0;
	}
}
/*串的提取
 *   在串s中的index开始长度为length的子串提取到temp串中
 * */
datatype HSsub(HString* temp, const HString* s, int index, int length) {
	if (index < 0 || index > s->len)
		return ERROR;
	if (length > s->len)
		length = s->len - index;
	temp->len = length;
	temp->ch = (char*) malloc(length * sizeof(char));
	if (!temp->ch)
		return OVERFLOW;
	int i;
	for (i = 0; i < length; i++) {
		*(temp->ch + i) = *(s->ch + index + i);
	}
	*(temp->ch + temp->len) = '\0';
	return OK;
}
//串的替换,把串s的从index开始长度为length的子串,用串t替换掉
datatype HSReplace(HString* s, int index, int length, const HString*t) {
	if (index < 0 || index > s->len)
		return ERROR;
	//如果length大于串s的长度就替换掉从index后的所有字符
	if (length > s->len)
		length = s->len;
	int i;
	for (i = 0; i < length; i++) {
		*(s->ch + i + index) = *(t->ch + i);
	}
	*(s->ch + s->len) = '\0';
	return OK;
}
int main(int argc, char** argv) {
	// bulid string
	HString S;
	InitHString(&S);
	assigment_string(&S, "hello world!");
	PrintString(&S);
	printf("length=%d\n", GetLength(&S));

#if 0
	//localion
	int local=HSLocal(&S,'w');
	printf("local=%d\n",local);
	free(S.ch);
#endif 

#if 0
	// insert
	HString S1;
	InitHString(&S1);
	assigment_string(&S1,"****");
	HSInsert(&S,&S1,2);
	PrintString(&S);
	printf("length=%d\n",GetLength(&S));
	free(S1.ch);
#endif
#if 0	
	// copy
	HString S2;
	InitHString(&S2);
	assigment_string(&S2,"beijing");
	HSCopy(&S,&S2);
	PrintString(&S);
	printf("length=%d\n",GetLength(&S));
	free(S.ch);
	free(S2.ch);
#endif
#if 0
	//cat 
	HString S3;
	InitHString(&S3);
	assigment_string(&S3,"");
	HSCat(&S,&S3);
	PrintString(&S);
	printf("length=%d\n",GetLength(&S));
	free(S3.ch);
	free(S.ch);
#endif 

#if 0
	// delete 
	HSdel(&S,2,5);
	PrintString(&S);
	printf("length=%d\n",GetLength(&S));
	free(S.ch);
#endif 

#if 0
	// complar 
	HString S4;
	InitHString(&S4);
	assigment_string(&S4,"hello world!");
	datatype ret=HScomp(&S,&S4);
	if(ret>0)
	printf("S>S4\n");
	else if(ret<0)
	printf("S<S4\n");
	else
	printf("S=S4\n");
	free(S4.ch);
	free(S.ch);
#endif

#if 0
	// sub
	HString S5;
	HSsub(&S5,&S,2,5);
	PrintString(&S5);
	printf("length=%d\n",GetLength(&S5));
	free(S.ch);
	free(S5.ch);
#endif

#if 1       
	// replace
	HString S6;
	InitHString(&S6);
	assigment_string(&S6, "************************************");
	HSReplace(&S, 2, 50, &S6);
	PrintString(&S);
	printf("length=%d\n", GetLength(&S));
	free(S6.ch);
	free(S.ch);

#endif
	//		free(S.ch);
	return 0;
}


 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值