串的动态存储分配

      串:由零个或者多个字符组成的有限序列。零个字符的串称为空串,和空格串【一个或多个空格诸城的串】有区别,请注意比较。在串的抽象数据类型中,有五个操作组成最小操作子集,分别是串赋值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 }

 

你可能感兴趣的:(动态)