串的动态存储分配

串:由零个或者多个字符组成的有限序列。零个字符的串称为空串,和空格串【一个或多个空格诸城的串】有区别,请注意比较。在串的抽象数据类型中,有五个操作组成最小操作子集,分别是串赋值StrAssign,串比较StrCompare,求串长StrLength ,串联接Concat,求子串SubString。现以串的动态存储结构为例,将5个基本操作实现如下:

具体介绍详见注释。

  1 /**
  2 在串的抽象数据类型的13中操作中:串赋值StrAssign,串比较StrCompare,求串长StrLength
  3 串连接Concat,求子串SubString构成串类型的最小操作子集
  4
  5 串有三种表示方法:
  6     定长顺序表示
  7     堆分配存储表示
  8     块链存储表示
  9 */
 10
 11 //主要介绍动态分配:对分配储存表示
 12 //仍然以一组地址连续的存储单元来存放串值字符序列,但他们的存储空间是在程序执行的过程中动态分配的。
 13 //C语言中有一个称之为“堆”自由存储区,并有malloc和free函数来管理
 14 #include <stdio.h>
 15 #include <stdlib.h>
 16 #include <string.h>
 17 //------------------串的堆分配存储结构-----------------
 18 typedef struct
 19 {
 20     char *ch;  //若是非空串,则按串长分配存储区,否则ch为NULL
 21     int length;//串长度
 22 } HString;
 23
 24 //---------------------串插入操作-----------------------
 25 void StrInsert(HString &S,int pos,HString T)
 26 {
 27     //1<=pos<=StrLength(S)+1,在串S的第pos个字符之前插入串T
 28     if ( pos<1 || pos>S.length+1 )
 29     {
 30         printf("插入位置有误,请确认后重新输入\n");
 31         getchar();
 32         exit(1);
 33     }
 34     if (T.length)//T非空,则重新分配空间,插入T
 35     {
 36         if(!(S.ch = (char*)realloc(S.ch,(S.length+T.length)*sizeof(char))))
 37         {
 38             printf("空间重新分配有误,任意键退出!\n");
 39             getchar();
 40             exit(1);
 41         }
 42         for (int i = S.length-1 ; i >= pos-1; --i)
 43         {
 44             /* 为插入T腾出位置 ,从最后一个全体向后挪动T.length个长度*/
 45             S.ch[i+T.length] = S.ch[i];
 46         }
 47         for (int i = 0 ; i < T.length; ++i)
 48         {
 49             /* 将T中的字符插入到S中 */
 50             S.ch[i+pos-1] = T.ch[i];
 51         }
 52         S.length +=T.length;
 53     }
 54 }
 55 //-------------------串的五种基本操作-------------------
 56 void StrAssign(HString &T,char *chars)
 57 {
 58     //生成一个其值等于串常量chars的串T
 59
 60     if(T.ch)
 61     {
 62         /* 释放T原有空间 */
 63         free(T.ch);
 64     }
 65     int count = 0;//计算字符串长度;
 66     char *c = NULL;
 67
 68     for(count = 0,c = chars; *c ; ++count,++c);//求chars的长度count
 69     if (!count)
 70     {
 71         /* 空串 */
 72         T.ch = NULL;
 73         T.length = 0;
 74     }
 75     else
 76     {
 77         if (!(T.ch = (char *)malloc(count * sizeof(char))))
 78         {
 79             printf("分配存储空间有误!\n");
 80             exit(1);
 81         }
 82         for (int i = 0; i < count; ++i)
 83         {
 84             T.ch[i] = chars[i];
 85         }
 86         T.length = count;
 87     }
 88
 89 }
 90
 91 //---------------------------求串长度-----------------------
 92 int StrLength(HString S)
 93 {
 94     //返回S的元素个数,称为串的长度
 95     return S.length;
 96 }
 97
 98 //--------------------------串比较函数------------------------
 99 int StrCompare(HString S,HString T)
100 {
101     //若S>T,则返回值大于0;若S<T,则返回值<0;若S=T,则返回值=0
102     for (int i = 0; i < S.length && i < T.length; ++i)
103     {
104         if (S.ch[i] != T.ch[i])
105         {
106             return S.ch[i] - T.ch[i];
107         }
108     }
109     return S.length - T.length;
110 }
111
112 //--------------------------串清除函数------------------------
113 void ClearString(HString &S)
114 {
115     //将串S清除为空串
116     if (S.ch)
117     {
118         free(S.ch);
119         S.length = 0;
120     }
121     S.length = 0;
122 }
123
124 //--------------------------串联接函数------------------------
125 void Concat(HString &T,HString S1,HString S2)
126 {
127     //用串T返回串S1和串S2联接给成的新串
128     if (!T.ch)
129     {
130         free(T.ch);//释放旧空间
131     }
132     if (!(T.ch = (char*)malloc((S1.length+S2.length)*sizeof(char))))
133     {
134         printf("分配存储空间有误!\n");
135         exit(1);
136     }
137     //将两个串联接起来
138     for (int i = 0; i < S1.length; ++i)
139     {
140         T.ch[i] = S1.ch[i];
141     }
142     T.length = S1.length + S2.length;
143     for (int i = 0; i < S2.length; ++i)
144     {
145         T.ch[i+S1.length] = S2.ch[i];
146     }
147 }
148
149 //----------------------------求子串函数----------------------------
150 void SubString(HString &Sub,HString S,int pos,int len)
151 {
152     //用Sub返回串S的第pos个字符起长度为len的子串
153     //其中,1<=pos<=StrLength(S)且  0<=len<=StrLength(S)-pos+1
154     if (pos<1 || pos>S.length || len<0 || len>S.length-pos+1)
155     {
156         printf("输入的求子串位置有误,请确认后重新输入!\n");
157     }
158     if (Sub.ch)
159     {
160         free(Sub.ch); //释放旧空间
161     }
162     if(!len)
163     {
164         //空子串
165         Sub.ch = NULL;
166         Sub.length = 0;
167
168     }
169     else
170     {
171         Sub.ch = (char*)malloc(len * sizeof(char));
172         for (int i = 0; i < len; ++i)
173         {
174             Sub.ch[i] = S.ch[pos+i-1];
175         }
176         Sub.length = len;
177
178     }
179 }
180 //--------------------------输出串内容---------------------------
181 void PrintStr(HString S)
182 {
183     if(S.ch)
184     {
185         for(int i=0; i<S.length; ++i)
186         {
187             printf("%c",S.ch[i]);
188         }
189         printf("\n");
190     }
191     else
192     {
193         printf("该串是空串!\n");
194     }
195 }
196
197 int main(int argc, char const *argv[])
198 {
199     char *c1 = "Hello,this is a test for String";
200     char *c2 = "I‘m string2";
201     HString s1,s2,s3;
202     //先将s1,s2,s3置为空串
203     s1.ch = NULL;
204     s1.length = 0;
205     s2.ch = NULL;
206     s2.length = 0;
207     s3.ch = NULL;
208     s3.length = 0;
209     //测试串赋值
210     StrAssign(s1,c1);
211     StrAssign(s2,c2);
212     printf("两个串赋值之后:\n");
213     PrintStr(s1);
214     PrintStr(s2);
215     //测试串比较
216     printf("%d\n",StrCompare(s1,s2));
217     //测试串连接
218     Concat(s3,s1,s2);
219     PrintStr(s3);
220     //测试求子串
221     SubString(s3,s1,1,5);
222     printf("子串:");
223     PrintStr(s3);
224     //测试清空串
225     ClearString(s3);
226     printf("清空该串后,输出结果为:");
227     PrintStr(s3);//无输出结果(串的内容为空),串长度为0
228     return 0;
229 }
时间: 2024-07-29 17:28:57

串的动态存储分配的相关文章

C/C++ 动态存储分配

C语言的动态分配函数: malloc(m):开辟m字节长度的地址空间,并返回这段空间的首地址 sizeof(x):计算变量x的长度 free(p):释放指针p所指变量的存储空间,即彻底删除一个变量 C++的动态存储分配: new  类型名T(初值列表) 功能:申请用于存放T类型对象的内存空间,并依初值列表赋以初值 结果值: 成功:T类型的指针,指向新分配的内存 失败:0(NULL) delete 指针P 功能:释放指针P所指向的内存.P必须是new操作的返回值

C语言动态存储分配

动态存储分配 C语言支持动态存储分配,即在程序执行期间分配内存单元的能力,利用动态存储分配,可以根据需要设计扩大(或缩小)的数据结构,虽然可以适用于所有类型的数据,但是动态存储分配更常用于字符串.数组和结构体 本文地址:http://www.cnblogs.com/archimedes/p/c-dynamic-storage-allocation.html,转载请注明源地址. 1.内存分配函数 3种内存分配函数都是声明在<stdlib.h>中: malloc函数--分配内存块,但是不对内存块进

实现一个动态存储分配

如何自己实现一个动态存储的分配机制,当然有很多的存储的分配方法,关键在于"堆"的管理. 这里我们使用"隐式链表"的方法实现对"堆"的分配. 而且分配的单位是"字",这里的字是4个字节,而且我们分配的内存都按8字节(也就是双字)对齐. 上图中一个空格代表一个字(4字节) 也就是我们的堆开始三个字是堆的对齐和头部用的.最后是堆的尾. 上图是我们堆的"分配块"的头部,由于我们的堆是以8字节对齐的,也就是分配的最小

指针和动态存储分配

1 指针 指针是C语言的基本概念,每种数据类型都有相应的指针类型.指针类型变量存放的值实际上就是内存地址.指针的最基本操作: & 取地址 * 去引用(间接引用) 如: int i, *pi              //其中 i 是整型变量,pi 是指向整数的指针. pi = &i ;             //则 &i 返回i的地址并把它赋值给 pi ,若要给 i 赋值,可以写成 i = 10 ; 或者 *pi = 10 ; pi 之前的 * 是去引用 , 10 并未存放指针里

C++ 动态内存分配(6种情况,好几个例子)

1.堆内存分配 : C/C++定义了4个内存区间: 代码区,全局变量与静态变量区,局部变量区即栈区,动态存储区,即堆(heap)区或自由存储区(free store). 堆的概念: 通常定义变量(或对象),编译器在编译时都可以根据该变量(或对象)的类型知道所需内存空间的大小,从而系统在适当的时候为他们分配确定的存储空间.这种内存分配称为静态存储分配: 有些操作对象只在程序运行时才能确定,这样编译时就无法为他们预定存储空间,只能在程序运行时,系统根据运行时的要求进行内存分配,这种方法称为动态存储分

Java中数据存储分配

(1)内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编 译时就可以给他们分配固定的内存空间.这种分配策略要求程序代码中不允许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为 它们都会导致编译程序无法计算准确的存储空间需求. 栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的.和静态存 储分配相反,在栈式存储方案中,程序对

【Cpp】考点·堆栈&amp;动态内存分配

动态内存分配 堆内存分配与释放 C/C++定义了四个内存区间:代码区,全局变量与静态变量区,局部变量区(栈区),动态内存区(堆区) 通常定义变量(或对象),编译器在编译时都可以根据该变量(或对象)的类型知道所需内存空间的大小,从而系统在适当的时候为他们分配确定的存储空间.这种内存分配称为静态存储分配.有些操作对象只在程序运行时才确定,这样编译时无法为他们预定存储空间,只能在程序运行时,系统根据运行时的要求进行内存分配,这种方法称为动态存储分配.所有动态存储分配都在堆区中进行. 当程序运行到需要一

c++动态内存分配 浅析

用new 运算符实现动态内存分配 P = new T; T是任意类型名,P是类型为T * 的指针. 动态分配出一片大小为 sizeof(T)字节的内存空间,并且将该 内存空间的起始地址赋值给P. P = new T[N]; T :任意类型名 P :类型为T * 的指针 N :要分配的数组元素的个数,可以是整型表达式 动态分配出一片大小为 sizeof(T)字节的内存空间,并且 将该内存空间的起始地址赋值给P. int * pn; 2.int i = 5; 3.pn = new int[i * 2

SQLite剖析之动态内存分配

SQLite通过动态内存分配来获取各种对象(例如数据库连接和SQL预处理语句)所需内存.建立数据库文件的内存Cache.以及保存查询结果.我们做了很多努力来让SQLite的动态内存分配子系统可靠.可预测.健壮并且高效.本文概述SQLite的动态内存分配,软件开发人员在使用SQLite时可以据此获得最佳性能. 1.特性    SQLite内核和它的内存分配子系统提供以下特性:    (1)对内存分配失败的健壮处理.如果一个内存分配请求失败(即malloc()或realloc()返回NULL),SQ