串的动态存储分配

      串:由零个或者多个字符组成的有限序列。零个字符的串称为空串,和空格串【一个或多个空格诸城的串】有区别,请注意比较。在串的抽象数据类型中,有五个操作组成最小操作子集,分别是串赋值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("插入位置有误,请确认后重新输入
");
 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("空间重新分配有误,任意键退出!
");
 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("分配存储空间有误!
");
 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("分配存储空间有误!
");
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("输入的求子串位置有误,请确认后重新输入!
");
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("
");
190     }
191     else
192     {
193         printf("该串是空串!
");
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("两个串赋值之后:
");
213     PrintStr(s1);
214     PrintStr(s2);
215     //测试串比较
216     printf("%d
",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 }
原文地址:https://www.cnblogs.com/wujiyang/p/4420084.html