串的堆分配存储表示

一、堆分配存储概述

堆分配内存仍是一组地址连续的存储单元来存放串值字符序列,但是存储空间实在程序执行过程中动态分配而得。在C语言中,存在一个称为“堆”的自由存储区,并由C语言的动态分配函数malloc()和free()来管理。利用函数malloc()为每个新产生的串分配一块实际串长所需的存储空间,若分配成功,则返回一个指向起始地址的指针,作为串的基址,同时为了方便以后的处理,约定串长也作为存储结构的一部分。

二、串的堆分配存储结构


三、串的操作

//1、初始化(产生空串)字符串S
void InitString(pHString S);
//2、将S清为空串
void ClearString(pHString S);
//3、生成一个其值等于串常量chars的串S
void StrAssign(pHString S, char *chars);
//4、显示字符串
void StrShow(pHString S);
//5、复制串S到T
void StrCopy(pHString T, pHString S);
//6、判断串是否为空,若为空返回True,否则返回false
bool StrEmpty(pHString S);
//7、比较两个串的最前面字符的ASCII码的大小,若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
int StrCompare(pHString S, pHString T);
//8、返回S的元素个数,称为串的长度
int StrLength(pHString &S);
//9、用T返回由S1和S2联接而成的新串
void StrConcat(pHString S1, pHString S2, pHString T);
//10、用Sub返回串S的第pos个字符起长度为len的子串。
bool StrSub(pHString Sub, pHString S, int pos, int len);
//11、找出子串T值主串S中的位置(与子串首字符相等的位置)
int Index1(pHString S, pHString T);
//12、 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。
int Index2(pHString S, pHString T, int pos);
//13、从串S中删除第pos个字符起长度为len的子串,从新申请空间
bool StrDelete1(pHString S, int pos, int len);
//14、从串S中删除第pos个字符起长度为len的子串,调整内存空间
bool StrDelete2(pHString S, int pos, int len);
typedef struct HString
{char * ch; // 若是非空串,则按串长分配存储区,否则ch为NULLint length; // 串长度
}HString,*pHString;

1、初始化(产生空串)字符串S

void InitString(pHString S)
{ S->ch = NULL;S->length = 0;
}

2、将S清为空串

void ClearString(pHString S)
{ free(S->ch);S->ch = NULL;S->length = 0;
}

3、生成一个其值等于串常量chars的串S

void StrAssign(pHString S, char *chars)
{int i, j;if (S->ch)//若S的指针不为空则释放S指针域所指向的空间free(S->ch); // 释放S原有空间i = strlen(chars); // 求chars的长度iif (!i)//若果字符串为空则清空S(相当于复制了一个空字符串){ // chars的长度为0S->ch = NULL;S->length = 0;}else{ // chars的长度不为0S->ch = (char*)malloc(i * sizeof(char)); // 分配大小跟chars大小相同的串空间if (!S->ch) // 分配串空间失败exit(-1);for (j = 0; j < i; j++) // 复制串S->ch[j] = chars[j];S->length = i;}
}

4、显示字符串

void StrShow(pHString S)
{ int i;for (i = 0; i < S->length; i++)printf("%c", S->ch[i]);printf("\n");
}

5、复制串S到T

void StrCopy(pHString T,pHString S )
{if (T->ch)free(T->ch); // 释放T原有空间T->ch = (char *)malloc(S->length*(sizeof(char)));//申请内存if (T->ch == NULL){printf("内存分配失败!");exit(-1);}for (int i = 0; i < S->length; i++)//逐一复制{T->ch[i] = S->ch[i];}T->length = S->length;//复制串长}

6、判断串是否为空,若为空返回True,否则返回false

bool StrEmpty(pHString S)
{if (S->length==0&&S->ch==NULL)//空串标志{return true;}else{return false;}
}

7、比较两个串的最前面字符的ASCII码的大小,若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0

8、返回S的元素个数,称为串的长度

int StrLength(pHString &S)
{ return S->length;
}

9、用T返回由S1和S2联接而成的新串

void StrConcat(pHString S1, pHString S2, pHString T)
{if (T->ch)free(T->ch); // 释放T原有空间T->ch = (char *)malloc((S1->length + S2->length)*(sizeof(char)));//申请内存if (T->ch == NULL){printf("内存分配失败!");exit(-1);}for (int i = 0; i < S1->length; i++)//逐一复制S1{T->ch[i] = S1->ch[i];}for (int i = 0; i < S2->length; i++)//接着逐一复制S2{T->ch[S1->length +i] = S2->ch[i];}T->length = (S1->length + S2->length);//复制总串长
}

10、用Sub返回串S的第pos个字符起(包括pos位置处的字符)长度为len的子串。

bool StrSub(pHString Sub,pHString S,int pos,int len)
{if (StrEmpty(S)){return    false;}if (pos<1||pos>S->length||len<0||len>S->length-pos+1)//排除不符合条件的pos和len{return false;}if (Sub->ch)free(Sub->ch); // 释放旧空间if (!len) // 空子串{Sub->ch = NULL;Sub->length = 0;}else{Sub->ch = (char*)malloc(len * sizeof(char));//申请len个空间if (!Sub->ch)exit(-1);}for (int i = pos; i < pos+len; i++)//逐个复制{Sub->ch[i - pos] = S->ch[i-1];}Sub->length = len;//保存长度return true;
}

11、找出子串T值在主串S中的位置(与子串首字符相等的位置)

int Index1(pHString S, pHString T)
{int i,j;for (i = 0; i < S->length; i++)//循环主串{if (S->ch[i] == T->ch[0])//如果在主串中找到一个与子串的第一个字符相等的字符时{int cont = 1;//计数变量for (j = 0; j < T->length; j++)//遍历子串{if (T->ch[j + 1] != S->ch[i + j+1])//在遍历T[0]时如果有不一致时退出遍历{break;}else//否则计数{cont++;if (cont == T->length)//当有T[0]个字符相同时则找到子串位置return i+1;}}}continue;}return 0;//不存在时
}

12、返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。

int Index2(pHString S, pHString T, int pos)
{int i, j;if (1 <= pos && pos <= S->length){i = pos;//从主串的第pos个字符开始和子串的第一个字符比较j = 0;while (i <= S->length && j < T->length){if (S->ch[i] == T->ch[j]) // 若找到主串字符与子串首字符相等时继续比较后继字符{++i;++j;}else // 指针后退,主串字符下标后移一位,重新开始匹配{i = i + 1;j = 0;}}if (j == T->length)//条件成立,子串在主串中return i - T->length+1;//因为i是下标,下标编程序号需要+1elsereturn 0;}elsereturn 0;
}

13、从串S中删除第pos个字符起长度为len的子串,从新申请空间

bool StrDelete1(pHString S, int pos, int len)
{if (StrEmpty(S))//S为空时{return  false;}if (pos<1||pos>S->length||len<0||len>S->length-pos+1)//pos和len不满足条件时{return false;}char *pNew = (char*)malloc((S->length - len) * sizeof(char));//从新申请空间if (pNew==NULL)//申请失败{return false;}for (int i = 0; i < pos-1; i++)//复制pos前的字符{pNew[i] = S->ch[i];}for (int i = pos+len-1; i < S->length; i++)//复制pos+len-1后的字符{pNew[i-len] = S->ch[i];}free(S->ch);//释放原内存S->ch = pNew;S->length = S->length - len;//更新长度return true;
}

14、从串S中删除第pos个字符起长度为len的子串,调整内存空间

bool StrDelete2(pHString S, int pos, int len)
{int i;if (StrEmpty(S))//S为空时{return    false;}if (S->length < pos + len - 1)//pos和len不满足条件时return false;for (i = pos - 1; i <= S->length - len; i++)//从pos + len - 1起,之后的元素向前移动S->ch[i] = S->ch[i + len];S->length -= len;S->ch = (char*)realloc(S->ch, S->length * sizeof(char));//调整S->ch的空间return true;
}

最后给出完整代码

// 串的堆分配存储.cpp
#include<string.h>
#include<malloc.h> // malloc()等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()typedef struct HString
{char * ch; // 若是非空串,则按串长分配存储区,否则ch为NULLint length; // 串长度
}HString,*pHString;//1、初始化(产生空串)字符串S
void InitString(pHString S);
//2、将S清为空串
void ClearString(pHString S);
//3、生成一个其值等于串常量chars的串S
void StrAssign(pHString S, char *chars);
//4、显示字符串
void StrShow(pHString S);
//5、复制串S到T
void StrCopy(pHString T, pHString S);
//6、判断串是否为空,若为空返回True,否则返回false
bool StrEmpty(pHString S);
//7、比较两个串的最前面字符的ASCII码的大小,若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
int StrCompare(pHString S, pHString T);
//8、返回S的元素个数,称为串的长度
int StrLength(pHString &S);
//9、用T返回由S1和S2联接而成的新串
void StrConcat(pHString S1, pHString S2, pHString T);
//10、用Sub返回串S的第pos个字符起长度为len的子串。
bool StrSub(pHString Sub, pHString S, int pos, int len);
//11、找出子串T值主串S中的位置(与子串首字符相等的位置)
int Index1(pHString S, pHString T);
//12、 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。
int Index2(pHString S, pHString T, int pos);
//13、从串S中删除第pos个字符起长度为len的子串,从新申请空间
bool StrDelete1(pHString S, int pos, int len);
//14、从串S中删除第pos个字符起长度为len的子串,调整内存空间
bool StrDelete2(pHString S, int pos, int len);int main()
{HString S, T, S1,Sub;InitString(&S);   InitString(&S1);    InitString(&T);InitString(&Sub);char chars[] = "god bye!";StrAssign(&S, chars);StrShow(&S);StrCopy(&T,&S);StrShow(&T);if (StrEmpty(&S)){printf("串S为空\n");}else{printf("串S不为空\n");}char char1[] = "god hello!";StrAssign(&T, char1);StrShow(&T);printf("比较S和T的结果%d\n", StrCompare(&S, &T));StrAssign(&S1, char1);printf("拼接字符串");StrShow(&S);StrShow(&S1);StrConcat(&S,&S1,&T);StrShow(&T);int pos = 3, len = 3;if (StrSub(&Sub, &S, pos, len)){StrShow(&Sub);}HString SS, TT;InitString(&SS);InitString(&TT);char char2[] = "abcdefghijklmn";char char3[] = "bcd";StrAssign(&SS, char2);StrShow(&SS);StrAssign(&TT, char3);printf("子串T在主串S中的位置为 %d\n", Index1(&SS,&TT));printf("子串T在主串S中的位置为 %d\n", Index2(&SS,&TT,5));StrShow(&SS);StrDelete1(&SS, pos, 3);StrShow(&SS);StrDelete2(&SS, pos, 3);StrShow(&SS);return 0;
}//1、初始化(产生空串)字符串S
void InitString(pHString S)
{ S->ch = NULL;S->length = 0;
}//2、将S清为空串
void ClearString(pHString S)
{ free(S->ch);S->ch = NULL;S->length = 0;
}
//3、生成一个其值等于串常量chars的串S
void StrAssign(pHString S, char *chars)
{int i, j;if (S->ch)//若S的指针不为空则释放S指针域所指向的空间free(S->ch); // 释放S原有空间i = strlen(chars); // 求chars的长度iif (!i)//若果字符串为空则清空S(相当于复制了一个空字符串){ // chars的长度为0S->ch = NULL;S->length = 0;}else{ // chars的长度不为0S->ch = (char*)malloc(i * sizeof(char)); // 分配大小跟chars大小相同的串空间if (!S->ch) // 分配串空间失败exit(-1);for (j = 0; j < i; j++) // 复制串S->ch[j] = chars[j];S->length = i;}
}
//4、显示字符串
void StrShow(pHString S)
{ int i;for (i = 0; i < S->length; i++)printf("%c", S->ch[i]);printf("\n");
}
//5、复制串S到T
void StrCopy(pHString T,pHString S )
{if (T->ch)free(T->ch); // 释放T原有空间T->ch = (char *)malloc(S->length*(sizeof(char)));//申请内存if (T->ch == NULL){printf("内存分配失败!");exit(-1);}for (int i = 0; i < S->length; i++)//逐一复制{T->ch[i] = S->ch[i];}T->length = S->length;//复制串长}
//6、判断串是否为空,若为空返回True,否则返回false
bool StrEmpty(pHString S)
{if (S->length==0&&S->ch==NULL)//空串标志{return true;}else{return false;}
}
//7、比较两个串的最前面字符的ASCII码的大小,若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
int StrCompare(pHString S, pHString T)
{for (int i = 0; i < S->length&&T->length; i++){if (S->ch[i]!=T->ch[i])//逐一比较字符{return   S->ch[i] - T->ch[i];//一旦不相等,则返回不想等字符的ASCII码的差值}}return S->length - T->length;//如果全部相等则返回其长度差值
}
//8、返回S的元素个数,称为串的长度
int StrLength(pHString &S)
{ return S->length;
}
//9、用T返回由S1和S2联接而成的新串
void StrConcat(pHString S1, pHString S2, pHString T)
{if (T->ch)free(T->ch); // 释放T原有空间T->ch = (char *)malloc((S1->length + S2->length)*(sizeof(char)));//申请内存if (T->ch == NULL){printf("内存分配失败!");exit(-1);}for (int i = 0; i < S1->length; i++)//逐一复制S1{T->ch[i] = S1->ch[i];}for (int i = 0; i < S2->length; i++)//接着逐一复制S2{T->ch[S1->length +i] = S2->ch[i];}T->length = (S1->length + S2->length);//复制总串长
}//10、用Sub返回串S的第pos个字符起(包括pos位置处的字符)长度为len的子串。
bool StrSub(pHString Sub,pHString S,int pos,int len)
{if (StrEmpty(S)){return    false;}if (pos<1||pos>S->length||len<0||len>S->length-pos+1)//排除不符合条件的pos和len{return false;}if (Sub->ch)free(Sub->ch); // 释放旧空间if (!len) // 空子串{Sub->ch = NULL;Sub->length = 0;}else{Sub->ch = (char*)malloc(len * sizeof(char));//申请len个空间if (!Sub->ch)exit(-1);}for (int i = pos; i < pos+len; i++)//逐个复制{Sub->ch[i - pos] = S->ch[i-1];}Sub->length = len;//保存长度return true;
}
//11、找出子串T值在主串S中的位置(与子串首字符相等的位置)
int Index1(pHString S, pHString T)
{int i,j;for (i = 0; i < S->length; i++)//循环主串{if (S->ch[i] == T->ch[0])//如果在主串中找到一个与子串的第一个字符相等的字符时{int cont = 1;//计数变量for (j = 0; j < T->length; j++)//遍历子串{if (T->ch[j + 1] != S->ch[i + j+1])//在遍历T[0]时如果有不一致时退出遍历{break;}else//否则计数{cont++;if (cont == T->length)//当有T[0]个字符相同时则找到子串位置return i+1;}}}continue;}return 0;//不存在时
}//12、返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0,其中,T非空,1≤pos≤StrLength(S)。
int Index2(pHString S, pHString T, int pos)
{int i, j;if (1 <= pos && pos <= S->length){i = pos;//从主串的第pos个字符开始和子串的第一个字符比较j = 0;while (i <= S->length && j < T->length){if (S->ch[i] == T->ch[j]) // 若找到主串字符与子串首字符相等时继续比较后继字符{++i;++j;}else // 指针后退,主串字符下标后移一位,重新开始匹配{i = i + 1;j = 0;}}if (j == T->length)//条件成立,子串在主串中return i - T->length+1;//因为i是下标,下标编程序号需要+1elsereturn 0;}elsereturn 0;
}//13、从串S中删除第pos个字符起长度为len的子串,从新申请空间
bool StrDelete1(pHString S, int pos, int len)
{if (StrEmpty(S))//S为空时{return  false;}if (pos<1||pos>S->length||len<0||len>S->length-pos+1)//pos和len不满足条件时{return false;}char *pNew = (char*)malloc((S->length - len) * sizeof(char));//从新申请空间if (pNew==NULL)//申请失败{return false;}for (int i = 0; i < pos-1; i++)//复制pos前的字符{pNew[i] = S->ch[i];}for (int i = pos+len-1; i < S->length; i++)//复制pos+len-1后的字符{pNew[i-len] = S->ch[i];}free(S->ch);//释放原内存S->ch = pNew;S->length = S->length - len;//更新长度return true;
}
//14、从串S中删除第pos个字符起长度为len的子串,调整内存空间
bool StrDelete2(pHString S, int pos, int len)
{int i;if (StrEmpty(S))//S为空时{return    false;}if (S->length < pos + len - 1)//pos和len不满足条件时return false;for (i = pos - 1; i <= S->length - len; i++)//从pos + len - 1起,之后的元素向前移动S->ch[i] = S->ch[i + len];S->length -= len;S->ch = (char*)realloc(S->ch, S->length * sizeof(char));//调整S->ch的空间return true;
}

数据结构笔记(十三)-- 串的堆分配存储表示相关推荐

  1. 串的堆分配存储c语言,数据结构c语言串的堆分配存储源程序

    <数据结构c语言串的堆分配存储源程序>由会员分享,可在线阅读,更多相关<数据结构c语言串的堆分配存储源程序(7页珍藏版)>请在人人文库网上搜索. 1.include#inclu ...

  2. 堆分配存储结构串的实现|C++

    堆分配存储结构串的实现方法是,提供一个足够大的存储空间.作为串的可利用空间,用来存储各串的串值. 每当建立一个新的串时,系统就从这个空间划分出一个大小和新串相同的空间给新串 若分配成功则返回一个指向起 ...

  3. 小蚂蚁学习数据结构(16)——串的堆分配储存代码演示

    2019独角兽企业重金招聘Python工程师标准>>> 根据对书上伪代码的理解,编写了这么一段堆分配储存的程序,反正运行着没有什么问题,看看网上其他人的代码,具体细节上有所不同外,思 ...

  4. a - 数据结构实验之串一:kmp简单应用_数据结构(C语言版)_笔记_3

    第4章 串 计算机上的非数值处理的对象基本上是字符串数据. 字符串一般简称为串. 4.1 串类型的定义 串(string)(或字符串)是由零个或多个字符组成的有限序列,一般记为其中s是串的名,单引号括 ...

  5. 数据结构笔记(十一)串

    串类型的定义 一.关于串的术语 串(string) 是由零个或者多个字符组成的有限序列,一般记做 s = 'a1a2a-an' s:是串变量名 a1a2a-an:是串值 ai(1<= i < ...

  6. 数据结构笔记(考研)

    目录 一.算法概述 算法的定义: 基本特性: 算法的基本要求 存储结构与逻辑结构 二.数据的逻辑结构 集合结构 线性结构 线性表 广义表 顺序表 数组: 查找算法 栈 队列 单链表 循环链表 双链表 ...

  7. 【考研408】算法与数据结构笔记

    文章目录 绪论 数据结构的基本概念 算法和算法评价 线性表 线性表的定义和基本操作 线性表的顺序表示 线性表的链式表示 栈和队列 栈 基本操作 栈的顺序存储结构 栈的链式存储 队列 队列常见的基本操作 ...

  8. acwing数据结构笔记(一)

    前言:书读百遍其义自见,代码也是一样,不断地写不断地背,才能熟练的掌握 y总:yxc 链接:https://www.acwing.com/ 来源:AcWing 著作权归作者所有.商业转载请联系作者获得 ...

  9. 数据结构-线性表-串

    串的定义 串(string)是由零个或多个字符组成的有限序列,又名叫字符串. 一般记为 s = "  "(n≥0),其中,s 是串的名称,用双引号括起来的字符序列是串的值. 串中的 ...

最新文章

  1. 父类引用指向子类对象
  2. 优化数据库大幅度提高Oracle的性能
  3. hadoop集群环境搭建
  4. Java进阶:volatile使用详解
  5. python调用函数示例_python 动态调用函数实例解析
  6. mfc搜索新建access字段_MFC ODBC类 Access数据库的操作
  7. C# ADO.NET
  8. 三种嵌入式操作系统的分析与比析
  9. linux内核定时器死机,浅析linux内核中timer定时器的生成和sofirq软中断调用流程
  10. 如何在windows下安装GIT
  11. 12306一直提示网络有问题_春运攻略:西安网友买票遇到的这些问题,这里有答案...
  12. Hadoop入门(1)
  13. PROTEL网络教程前
  14. Android Jetpack 系列篇(一) Data Binding
  15. win10或11非华为电脑安装最新的电脑管家(支持移动应用引擎)安装方法及问题解决
  16. 世纪佳缘 小秘书 (可自动吸引异性关注)
  17. iphone修改app名称_如何更改iPhone App名称100%!
  18. 404错误代码页面 调用自动获取小姐姐图片
  19. 一个简单的Android破解WIFI密码的方法(实用)
  20. windows服务创建

热门文章

  1. bzoj 1667: [Usaco2006 Oct]Cows on Skates滑旱冰的奶牛(BFS)
  2. 二维树状数组(bzoj 1452: [JSOI2009]Count)
  3. opencv中很有趣的仿射变换(Affine Transformation)
  4. C语言实现加密解密功能 附带详细注释源码
  5. rand(m,n) 续行
  6. 《算法分析与设计》课程任务
  7. Linked List Two Finish
  8. Android软件开发之SharedPreferences
  9. Android Spinner填充数据后设置默认值的问题
  10. [置顶] Android之Handler用法总结