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