首页 > 其他分享 >字符串-00002-堆上字符串-函数实现

字符串-00002-堆上字符串-函数实现

时间:2022-12-04 00:11:07浏览次数:68  
标签:pstr return index pch 00002 字符串 堆上 pstr1 size

  • myString.c,常用函数的实现
  • 头文件定义请参考:https://www.cnblogs.com/kxwslmsps/p/16949213.html
  • #include"myString.h"
    
    
    /**********************************************************************/
    /**********************************************************************/
    
    /**
    * @brief 功能:初始化字符数组 \n
    * @retval ERROR(0):pstr不存在,不可操作
    * @retval OK(1):初始化成功成功
    */
    status xxx_init(myString* pstr)
    {
    	if (pstr == NULL)
    	{
    		return ERROR;
    	}
    	pstr->pch = NULL;
    	pstr->capacity = 0;
    	pstr->size = 0;
    	return OK;
    }
    
    
    /**********************************************************************/
    /**********************************************************************/
    
    /**
    * @brief 功能:判空 \n
    * @retval ERROR(0):字符串不存在,不可操作
    * @retval FALSE(0):字符串非空
    * @retval TRUE(1):字符串为空
    */
    status xxx_empty(myString* pstr)
    {
    	if (pstr == NULL)
    	{
    		return ERROR;
    	}
    	return pstr->size == 0 ? TRUE : FALSE;
    }
    
    /**********************************************************************/
    /**********************************************************************/
    
    /**
    * @brief 功能:求堆上字符串字符长度,不包括结束标志杠0 \n
    * @return 返回字长串长度
    * @retval -1:字符串不存在,不可求长度
    * @retval 非负整数:字符串长度
    */
    int xxx_strlen(myString* pstr)
    {
    	if (pstr == NULL)
    	{
    		return -1;
    	}
    	return pstr->size;
    }
    
    
    /**********************************************************************/
    /**********************************************************************/
    
    /**
    * @brief 功能:清空堆上字符串 \n
    * @retval ERROR(0):字符串不存在,不可操作
    * @retval OK(1):清空成功,串空间及串容量不变,只是串长度变为0
    */
    status xxx_clear(myString* pstr)
    {
    	if (pstr == NULL)
    	{
    		return ERROR;
    	}
    	pstr->size = 0;
    	return OK;
    }
    
    
    /**********************************************************************/
    /**********************************************************************/
    
    /**
    * @brief 功能:清空 \n
    * @retval ERROR(0):字符串不存在,不可操作
    * @retval OK(1):清空成功
    */
    status xxx_destroy(myString* pstr)
    {
    	if (pstr == NULL)
    	{
    		return ERROR;
    	}
    	if (pstr->pch != NULL)
    	{
    		free(pstr->pch);
    		pstr->pch = NULL;
    	}
    	pstr->capacity = 0;
    	pstr->size = 0;
    	return OK;
    }
    
    /**********************************************************************/
    /**********************************************************************/
    
    /**
    * @brief 功能:打印字符数组 \n
    */
    void xxx_output(myString* pstr)
    {
    	if (pstr == NULL || pstr->pch == NULL)
    	{
    		return;
    	}
    	int i = 0;
    	printf("capacity=%d,size=%d,mystr=", pstr->capacity, pstr->size);
    	while (i < pstr->size)
    	{
    		printf("%c", pstr->pch[i]);
    		++i;
    	}
    	
    	if (pstr->pch == NULL)
    	{
    		printf("已被销毁\n");
    	}
    	else if (pstr->size == 0)
    	{
    		printf("已被清空\n");
    	}
    	else
    	{
    		printf("\n");
    	}
    	
    }
    
    
    /**********************************************************************/
    /**********************************************************************/
    
    /**
    * @brief 功能:将字符串src字符赋值给堆上字符串pstr \n
    * @param[in] pstr:目的字符串
    * @param[in] src:源字符串。当src为空时,pstr将被置空
    * @retval ERROR(0):字符串不存在,不可操作
    * @retval OVERFLOW(-2):赋值失败,pstr无法容纳src,且开辟新空间失败
    * @retval OK(1):赋值成功。当源串为空时,目的串被置空,但目的串堆上空间不变
    */
    status xxx_assign(myString* pstr, const char* src)
    {
    	if (pstr == NULL || src == NULL)
    	{
    		return ERROR;
    	}
    
    	// 若src为空串,将pstr置空
    	int size = strlen(src);
    	if (size == 0)
    	{
    		pstr->size = 0;
    		return OK;
    	}
    
    	// 若目的串的空间不足以容纳源串所有字符,则新开辟空间
    	if (pstr->capacity < size)
    	{
    		char* pch = (char*)realloc(pstr->pch, sizeof(char) * size);
    		if (pch == NULL)
    		{
    			return OVERFLOW;
    		}
    		// 更新pstr信息
    		pstr->pch = pch;
    		pstr->capacity = size;
    	}
    	
    	// 将源串字符拷贝到目的串
    	int i = 0;
    	while (i < size)
    	{
    		pstr->pch[i] = src[i];
    		++i;
    	}
    	pstr->size = size;
    	return OK;
    }
    
    
    /**********************************************************************/
    /**********************************************************************/
    
    /**
    * @brief 功能:拷贝堆上字符串\n
    * @param[in] pstr1:目地字符串
    * @param[in] pstr2:源字符串。当pstr2为空串时,结果是将pstr1置空
    * @retval ERROR(0):字符串不存在,不可操作
    * @retval OVERFLOW(-2):拷贝失败:pstr1无法容纳pstr2,且开辟新空间失败
    * @retval OK(1):拷贝成功
    */
    status xxx_copy(myString* pstr1, const myString* pstr2)
    {
    	if (pstr1 == NULL || pstr2 == NULL)
    	{
    		return ERROR;
    	}
    	
    	// 源串为空时,目的串置空
    	if (pstr2->size == 0)
    	{
    		pstr1->size = 0;
    		return OK;
    	}
    	
    	// 若目的串的空间不足以容纳源串所有字符,则新开辟空间
    	if (pstr1->capacity < pstr2->size)
    	{
    		char* pch = (char*)realloc(pstr1->pch, sizeof(char) * pstr2->size);
    		if (pch == NULL)
    		{
    			return OVERFLOW;
    		}
    		// 更新pstr信息
    		pstr1->pch = pch;
    		pstr1->capacity = pstr2->size;
    	}
    
    	// 拷贝源串字符串到新建空间
    	int i = 0;
    	while (i < pstr2->size)				
    	{
    		pstr1->pch[i] = pstr2->pch[i];
    		++i;
    	}
    	pstr1->size = pstr2->size;
    	return OK;
    }
    
    
    /**********************************************************************/
    /**********************************************************************/
    
    /**
    * @brief 功能:比较2个堆字符串大小 \n
    * @parm[in] pstr1:待比较字符串
    * @parm[in] pstr2:待比较字符串
    * @retval 1:pstr1>pstr2
    * @retval -1:pstr2<pstr2
    * @retval 0:pstr1==pstr2
    
    */
    int xxx_compare(const myString* pstr1, const myString* pstr2)
    {
    	assert(pstr1 != NULL && pstr2 != NULL);
    	int s1 = pstr1->size;
    	int s2 = pstr2->size;
    
    	// i作遍历指针,min记录2串较短者长度
    	int i = 0;		
    	int min = s1 <s2 ? s1 : s2;	
    
    	// 逐个比较2串字符,若相等且未比较完前min个字符,继续比较后继字符
    	// 若不相等,或已比较完前min个字符,则跳出循环
    	while (i < min && pstr1->pch[i] == pstr2->pch[i])	
    	{
    		++i;
    	}
    
    	// 说明前min个字符比较完且前min个字符相等,只须比较2串长度即可
    	if (i == min)	
    	{
    		return s1 == s2 ? 0 : (s1 > s2 ? 1 : -1);
    		
    	}
    	// 否则i<min则说明pstr1->[i]!=pstr2->pch[i]必成立,只需比较当前字符大小即可
    	return pstr1->pch[i] > pstr1->pch[i] ? 1 : -1;
    }
    
    
    /**********************************************************************/
    /**********************************************************************/
    
    /**
    * @brief 功能:拼接2个字符数组后将结果存放于pstr \n
    * @param[in] pstr1:待拼接字符串1
    * @param[in] pstr2:待拼接字符串2
    * @param[out] pstr:存放拼接结果
    * @retval ERROR(0):字符串不存在,不可操作
    * @retval OVERFLOW(-2):拼接失败:结果串空间不足,且开辟新空间失败
    * @retval OK(1):拼接成功:包括2源串均为空时,结果串被置空
    */
    status xxx_concat(myString* pstr, const myString* pstr1, const myString* pstr2)
    {
    	if (pstr == NULL || pstr1 == NULL || pstr2 == NULL)
    	{
    		return ERROR;
    	}
    
    	// 2源串都为空时,结果串置空
    	if (pstr1->size == 0 && pstr2->size == 0)	
    	{
    		pstr->size = 0;
    		return OK;
    	}
    	int s1 = pstr1->size;			// pstr1长度
    	int s2 = pstr2->size;			// pstr2长度
    
    	// 开辟堆上新空间,用来存放2串的字符
    	if (pstr->capacity < s1 + s2)
    	{
    		char* pch = (char*)realloc(pstr->pch, sizeof(char) * (s1 + s2));
    		if (pch == NULL)
    		{
    			return OVERFLOW;
    		}
    		// 更新pstr信息
    		pstr->pch = pch;
    		pstr->capacity = s1 + s2;
    	}
    
    	// 拷贝pstr1到目的串[0,s1-1]空间上
    	int i = 0;
    	while (i < s1)					
    	{
    		pstr->pch[i] = pstr1->pch[i];
    		++i;
    	}
    
    	// 拷贝pstr2到目的串[s1,s1+s2-1]空间上
    	int j = 0;
    	while	(j < s2)				
    	{
    		pstr->pch[i+j] = pstr2->pch[j];
    		++j;
    	}
    	pstr->size = s1 + s2;
    	return OK;
    }
    
    
    /**********************************************************************/
    /**********************************************************************/
    
    /**
    * @brief 功能:从母串上截取n个连续字符存放于子串 \n
    * @param[in] pstr:母串
    * @param[out] psub:子串:截取母串连续n个字符后存放于子串
    * @param[in] index:截取字符的开始下标,取值为[0,pstr->size-1]
    * @param[in] n:n范围[0,size-index],当n>size-index时,n取size-index
    * @retval ERROR(0):字符串不存在,不可操作
    * @retval FALSE(0):操作失败:母串为空,且要求在空串截取若干个字符导致失败
    * @retval ERR_PARA(-1):index或n参数不符合要求 
    * @retval OVERFLOW(-2):开辟空间失败,内存溢出,操作失败
    * @retval OK(1):操作成功,包括在母串首字符位置截取0个字符,视为操作成功
    */
    status xxx_subStr(myString* pstr, myString* psub, int index, int n)
    {
    	if (pstr == NULL || psub == NULL)
    	{
    		return ERROR;
    	}
    	if (pstr ->size == 0)
    	{
    		// 母串为空,但在空串上截取0个字符,视为求子串成功
    		if (index == 0 && n == 0)
    		{
    			return OK;	
    		}
    		return FALSE;
    	}
    
    	int size = pstr->size;		// 母串长度
    
    	// 下标index不符合,或截取字符个数n不符合
    	if (index<0 || index>size - 1 || n<0)
    	{
    		return ERR_PARA;
    	}
    	// 当待截取个数>可截取个数时,则只截取要截取个数
    	if (n > size - index)
    	{
    		n = size - index;
    	}
    	// 若psub空间不足以容纳n个字符,则新开n个字符空间
    	if (psub->capacity < n)
    	{
    		char* pch = (char*)realloc(psub->pch, sizeof(char) * n);
    		if (pch == NULL)
    		{
    			return OVERFLOW;
    		}
    		// 更新pstr信息
    		psub->pch = pch;
    		psub->capacity = n;
    	}
    
    	// 从母串index处开始拷贝n个字符到psub
    	int i = 0;
    	while (i < n)
    	{
    		psub->pch[i] = pstr->pch[index + i];
    		++i;
    	}
    
    
    	psub->size = n;
    	return OK;
    }
    
    
    /**********************************************************************/
    /**********************************************************************/
    
    /**
    * @brief 功能:在串1插入串2 \n
    * @param[in] pstr1:串1为被插串
    * @param[in] pstr2:串2为待插串
    * @param[in] index:串2插入在串1下标index处,index范围[0,pstr->size-1]
    * @param[in] n:截取的字符数n,取值为[0,pstr->size]
    * @retval ERROR(0):字符串不存在,不可操作
    * @retval ERR_PARA(-1):插入失败:插入下标index不合理
    * @retval OVERFLOW(-2):插入失败:串1空间不足,且开辟新空间失败
    * @retval OK(1):插入成功:包括在串1插入空串,亦视为插入成功
    */
    status xxx_insert(myString* pstr1, myString* pstr2, int index)
    {
    	if (pstr1 == NULL || pstr2 == NULL)
    	{
    		return ERROR;
    	}
    	// 若待插字串为空,不做操作,视为插入成功
    	if (pstr2->size == 0)
    	{
    		return OK;
    	}
    
    	if (index<0 || index> pstr1->size)	// 插入位置不合理
    	{
    		return ERR_PARA;
    	}
    
    	int s1 = pstr1->size;
    	int s2 = pstr2->size;
    	if (pstr1->capacity < s1+s2 )
    	{
    		char* pch = (char*)realloc(pstr1->pch, sizeof(char) * (s1 + s2));
    		if (pch == NULL)
    		{
    			return OVERFLOW;
    		}
    		pstr1->pch = pch;
    		pstr1->capacity = pstr1->size + pstr2->size;
    	}
    	// 将串1[index,s1]区域内字符全部依次往后挪s2个位置
    	int i = s1 - 1;
    	while (i >= index)
    	{
    		pstr1->pch[i + s2] = pstr1->pch[i];
    		--i;
    	}
    
    	// 将串的pstr2->size个元素依次拷贝到串1区域[index,index+s2]中
    	int j = 0;
    	while (j < pstr2->size)
    	{
    		pstr1->pch[index + j] = pstr2->pch[j];
    		++j;
    	}
    	pstr1->size += pstr2->size;
    	return OK;
    }
    
    /**********************************************************************/
    /**********************************************************************/
    
    /**
    * @brief 功能:删除字符数组给定下标处连续n个元素 \n
    * @param[in] pstr:待删串
    * @param[in] index:在index处开始删除,index取值[0,size-1]
    * @param[in] n:待删字符个数,n取值[0,size-index]
    * @retval ERROR(0):字符串不存在,不可操作
    * @retval ERR_PARA(-1):pstr为空,或index,n参数不合理,操作失败
    * @retval OK(1):操作成功
    */
    status xxx_remove(myString* pstr, int index, int n)
    {
    	if (pstr == NULL)
    	{
    		return ERROR;
    	}
    	int size = pstr->size;
    
    	// index不在[0,size]范围内,或n<1,无须删除。且包含了pstr为空的情况
    	if (index<0 || index>size - 1 || n < 0)
    	{
    		return ERR_PARA;
    	}
    	
    	// x=size-index表示在index处及之后有x个字符可删除,而n为待删字符个数
    	// if(待删除字符个数>=可删除字符个数),则将x个字符全删除即可
    	// 故 while(n>x) 即 while(n>size-index),即while(index<size-n)
    	// 此为需要移动后继字符覆盖前边字符的前提条件,否则直接令pstr[index]='\0'
    	// 设下标j=index;则要求j<size-n
    	int j = index;
    	while (j<size-n)
    	{
    		pstr->pch[j] = pstr->pch[j + n];
    		++j;
    	}
    
    	// 若待删字符数n>可删字符数size-index,则将index及之后字符全删,剩 index个
    	// 否则只删n个字符,剩(size-n)个
    	pstr->size = n > size - index ? index : size - n;
    	return OK;
    }
    

      

标签:pstr,return,index,pch,00002,字符串,堆上,pstr1,size
From: https://www.cnblogs.com/kxwslmsps/p/16949223.html

相关文章