Detailed explanation of the heap implementation of string (string)----linear structure

The learning and implementation of linear tables such as linear tables, stacks, and queues have been completed before . Today, another important data structure in the linear structure, string , has been completed . Let me share it with you and make progress together.

String, also known as string.

In fact, a string is a sequence of characters consisting of one or more characters . Using strings can conveniently store all the information we want to store.

If we now need to store the specific name of a classmate, a famous quote, a paragraph, an article, these information include digital information, English information, Chinese information, punctuation marks, special symbols, etc. You can use a string to store it.

Strings have many operation methods, such as initializing strings, copying strings, retrieving strings, intercepting strings, connecting strings, inserting strings, deleting strings, replacing strings, comparing strings, etc. It is very convenient to use these methods Perform various operations on strings to meet user needs.

Strings can be divided into sequential strings and heap strings .

The sequence string is implemented by using a character array. Since the character array needs to open up a fixed storage space in advance, and it is not easy to expand, this article does not recommend the sequence string for the time being. I will share the specific code of the sequence string with you.

The heap string uses the heap method to dynamically open up memory space for the content of the string, which can effectively save memory resources, and is beneficial to the expansion operation and compatible operation of the string, which is convenient for users to operate.

The following is the specific implementation code of the string. If you have any questions or concerns, please leave a comment~

string definition

#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

#define STRING_INIT_SIZE 100

//定义字符串 string 类型 
typedef struct StringNode{
    
    
	char *content;			//字符串内容 content 
	int length;				//字符串长度 length 
}*String;

declaration of all methods

int initString(String &string);						//初始化线性化结构 串(string) 
int destroyString(String &string);					//销毁字符串string  
int isEmptyString(String &string);					//判断是否为空串 
int strLength(String &string);						//返回字符串的长度 
void printString(String &string);					//打印字符串string
int clearString(String &string);					//清空字符串
int assignString(String &string, char chars[]);					//生成一个值为常量为chars的字符串string 
int copyString(String &string, String s);						//拷贝字符串,将字符串s拷贝赋值给string 
int compareString(String &string, String s);					//对比两个字符串,若string>s,返回>0,相等返回0,否则返回<0
int concatString(String &string, String s1, String s2);			//将s1和s2连接的新串赋值给string 
int subString(String &string, String &s, int pos, int len);		//截取字符串,以s串返回string字符串第pos开始len个长度的串 
int indexString(String &string, String s, int pos);				//检索字符串,返回string串第pos位置后第一次和s串相同子串的开始位置,否则返回0 
int replaceString(String &string, String s1, String s2);		//替换字符串,以串s2替换掉string串中所有的串s1 
int insertString(String &string, String s, int pos);			//插入字符串,将子串s插入到string字符串的第pos个位置 
int deleteString(String &string, int pos, int len);				//删除字符串,删除string字符串中第pos个位置开始,长度为n的字串 

Initialize string data type
//使用字符数组对串进行初始化 
int assignString(String &string, char chars[])
{
    
    
	int i, j;
	char *p = chars;					//定义一个字符指针指向字符数组 
	while(*p != '\0' && *p != '\n')			//循环统计字符数组长度 
	{
    
    
		p++;
		i++;							//计数器累加 
	}
	
	string->content = (char *)malloc(i*sizeof(char));	//动态地为串的内容开辟相应地内存空间存储串信息 
	string->length = i; 				//设置串的长度 
	
	for(j = 0; j < i; j++)
	{
    
    
		string->content[j] = chars[j];		//将字符数组内容复制给串的内容	
	}
	string->content[j] = '\0';			//字符串内容的最后一位设置为字符结束符 
	return OK;						//返回结果 
}

copy string

//复制字符串,将字符串s的内容复制给string 
int copyString(String &string, String s)
{
    
    
	int length = s->length;					//记录字符串s的长度 
	if(length == 0)							//若字符串的长度为0,则直接清空string串,返回 
	{
    
    
		clearString(string);
		return OK;
	}
	else									//否则 
	{
    
    
		//根据新的内容使用realloc()函数重新为串string开辟内容空间 
		string->content = (char *)realloc(string->content, length*sizeof(char));
		char *p = s->content, *q = string->content;		//定义p指针指向s内容,q指针指向string内容 
		while(*p != '\0' && *p != '\n')			//使用p指针重复读取s之中的内容,直至s串结束 
		{
    
    
			*q = *p;				//将p指针中的内容赋值给q指针指向的内容,进行复制 
			p++;
			q++;					//p、q指针累加,指向串中的下一内容 
		}
		*q = '\0';					//复制完毕,q指针指向的string串以'\0'结束 
		string->length = s->length;			//更新串string的长度 
		return OK;			//返回结果 
	}
	
}

compare strings

//对两个字符串string和s进行比较,
//若string > s,返回 > 0;
//若string < s,返回 < 0;
//否则返回0 
int compareString(String &string, String s)
{
    
    
	//循环比较string串和s串,当string和s的第一个字符相等时,比较第2个,再相等比较第3个...,直至string串或s串结束 
	for(int i = 0; i < string->length && i < s->length; i++)
	{
    
    
		if(string->content[i] != s->content[i])			//若两个串的某个位置的字符串不等 
			return string->content[i] - s->content[i];		//返回它们的差值,即为结果(ASCLL码) 
	}
	return string->length - string->length;			//若持续相等,返回它们的长度的差值 
}

connection string

//将字符串s1和字符串s2连接成为新的字符串string 
int concatString(String &string, String s1, String s2)
{
    
    
	int length = s1->length + s2->length, i;	//记录s1和s2字符串长度之和 
	string->content = (char *)realloc(string->content, length*(sizeof(char)));		//重新为string串内容开辟此长度的空间 
	//通过循环的方式连接两个字符串 
	for(i = 0; i < length; i++)
	{
    
    
		if(i < s1->length)			//若 i < s1的长度,则先添加s1字符串内容 
			string->content[i] = s1->content[i];
		else						//之后再添加s2字符串的内容 
			string->content[i] = s2->content[i-(s1->length)];
	}
	string->content[i] = '\0';		//连接形成的新的字符串string以'\0'结束 
	string->length = length;		//更新字符串string的长度 
	
	return OK;		//返回结果 
}

intercept string

//截取字符串,把string字符串的第pos个位置开始,长度为len的子字符串截取下来,赋值给s返回 
int subString(String &string, String &s, int pos, int len)
{
    
    
	if(pos < 1 || pos > string->length || len < 0 || len > string->length+1)
		return ERROR;			//若截取参数有误,直接返回错误信息 
	
	int i = 0;			//定义计数器 
	s->content = (char *)malloc(len*sizeof(char));		//动态为s字符串开辟长度为len的字符串内容 
	s->length = len;					//并设置字符串的长度 
	
	//从字符串的第pos个位置开始,循环进行截取内容 
	for(i = pos-1; i < pos-1+len; i++)
	{
    
    
		s->content[i-(pos-1)] = string->content[i];		//截取内容赋值给s字符串 
	}
	
	s->content[i-(pos-1)] = '\0';		//为s字符串的最后字符'\0'作为字符串结束标志 
	return OK;		//返回结果 
}


insert string

//在字符串string的第pos个位置插入新的字符串s 
int insertString(String &string, String s, int pos)
{
    
    
	if(s->length == 0 || pos < 1 || pos > string->length+1)
		return ERROR;		//若插入参数有误,直接返回错误信息 
	
	int length = string->length + s->length;		//对插入的长度进行增加保存 
	
	int i = 0;
	String new_string; 				//定义新的new_string字符串准备接收 
	initString(new_string);			//初始化new_string字符串 
	new_string->content = (char *)malloc(length*sizeof(char));		//动态为该字符串开辟长度为length的空间 

	//循环通过3段连接的方式进行字符串的添加,暂添加至new_string 
	for(i = 0; i < length; i++)
	{
    
    
		if(i < pos-1)
			new_string->content[i] = string->content[i];	//添加pos之前string字符串的内容 
		else if(i >= pos-1 && i < pos - 1 + s->length)
			new_string->content[i] = s->content[i-(pos-1)];		//添加s字符串的内容 
		else
			new_string->content[i] = string->content[i-s->length];		//添加pos位置之后string字符串的内容 
	}
	new_string->content[i] = '\0';		//字符串new_string内容以'\0'结束标志 
	new_string->length = length;		//设置字符串长度 
	
	copyString(string, new_string); 	//进行字符串复制,即此时string便是已成功插入的字符串 
	return OK;		//返回结果 
}


delete string

//删除字符串string从第pos个位置开始,长度为len的子串 
int deleteString(String &string, int pos, int len)
{
    
    
	if(pos < 1 || pos > string->length || len < 1 || pos - 1 + len > string->length)
		return ERROR;		//若删除参数有误,直接返回错误信息 
		
	int i,j;
	String new_string;		//同插入字符串操作,定义新的字符串new_string 
	initString(new_string);			//初始化字符串 
	new_string->content = (char *)malloc((string->length-len)*(sizeof(char)));		//为新的字符串内容动态开辟空间 
	
	//循环通过2段字符串的连接进行子串的删除 
	for(i = 0, j = 0; i < string->length; i++)
	{
    
    
		if(i < pos-1)
			new_string->content[j++] = string->content[i];		//添加pos位置之前的string串的内容 
		if(i >= pos-1+len)
			new_string->content[j++] = string->content[i];		//添加pos-1+len位置之后string串的内容,便实现删除 
	}
	new_string->content[j] = '\0';				//字符串new_string内容以'\0'结束标志 
	new_string->length = string->length-len;	//设置字符串的长度 
	
	copyString(string, new_string);			//进行字符串复制,即此时string便是已成功删除子串的字符串 	
	return OK;			//返回结果 
}

replace string


//字符串替换操作,将string串中所有s1子串替换为s2子串 
int replaceString(String &string, String s1, String s2)
{
    
    
	if(string->length == 0)			//string为空串,直接返回 
		return ERROR;
	if(indexString(s2, s1, 1) != 0)		//s2中包含s1子串,会造成递归无限替换,直接返回 
		return ERROR;
	
	for(int i = 0; i < string->length; i++)			//循环检索所有的情况 
	{
    
    
		int j = indexString(string, s1, i+1);			//从第i+1个位置后检索string串是否包含s1串,若包含,返回子串开始位置 
		if(j > 0)			//若包含 
		{
    
    
			deleteString(string, j, s1->length);		//删除string中的从j位置开始的子串 s1 
			insertString(string, s2, j);				//添加子串s2 到字符串string的第j个位置,替换成功 
		}
	}
	
	return OK;			//返回结果 
}

search string

//从第pos个位置开始,检索string中是否包含子串s,若包含返回第一次发现子串的起始位置,否则返回0 
int indexString(String &string, String s, int pos)
{
    
    
	if(pos > string->length)
		return ERROR;			//若pos位置有误,直接返回 

	String new_string; 
	initString(new_string);			//定义并初始化新的字符串new_string 
	for(int i = pos-1; i < string->length; i++)		//从第pos个位置循环检索每一个子串 
	{
    
    
		subString(string, new_string, i+1, s->length);		//截取string串中的每个子串 
		if(compareString(new_string, s) == 0)		//若该子串和子串s相等,说明检索成功 
			return i+1;				//返回该子串的起始位置 
	}
	
	return FALSE;			//否则,返回false,即0 
}


String Empty, Empty, Destroy, Print String


//判断字符串string是否为空串 
int isEmptyString(String &string)
{
    
    
	if(string->length == 0)
		return TRUE;			//空串返回1 
	else
		return FALSE;			//否则返回0 
}


//返回字符串string的长度,冗余操作 
int strLength(String &string)
{
    
    
	return string->length;
}


//清空字符串string
int clearString(String &string)
{
    
    
	free(string->content);		//释放string字符串内容空间 
	string->content = NULL;		//设置string内容空间为NULL 
	string->length = 0;			//设置string内容长度为0 
	return OK;		//返回结果 
}


//销毁字符串string
int destroyString(String &string)
{
    
    
	clearString(string);		//清空字符串string
	
	free(string);			//释放字符串string空间 
	string = NULL;			//字符串string为NULL 
	
	return OK;			//返回结果 
}


//打印字符串string
void printString(String &string)
{
    
    
	printf("字符串的内容为:\n");
	printf("%s\n", string->content);
	printf("长度---->%d.\n", string->length);
	return;
}


Well, tomorrow I will share the sequence implementation code of the string with you when I have time. Come on~

Guess you like

Origin blog.csdn.net/weixin_43479947/article/details/113732358