————————————————————————————————————————————
- 定长顺序存储表示法
————————————————————————————————————————————
存储结构:
使用字符串数组作为存储,定义字符串数组长度为MAXSTRLEN+1(0位置用来存放字符串长度)
————————————————————————————————————————————
操作方法:
-
字符串赋值
通过将控制台输入的字符串赋值给串S1(从1开始存储),如果字符串长度超过限制,则截取越界前的数据存入。S1[0]位置存放字符串长度
-
字符串拷贝
对字符串遍历逐个拷贝(判断长度,仅拷贝长度范围内的)
-
字符串判空
判断字符串0位置是否为0
-
返回字符串长度
返回字符串0位置的值
-
打印字符串
在字符串长度范围内遍历并打印
-
清空字符串
字符串长度S[0]置为0
-
字符串联接
判断联接的两个字符串长度之和,如果长度之和在界限范围内,则字符串2接到字符串1后。
如果长度之和超过界限,进行截断。先存入字符串1,字符串1存入剩下的位置存字符串2。(如果字符串1本身就是界限长度,则留给字符串2的位置为空,不存入字符串2)
-
索引子串位置
定义两个临时变量 i 和 j 存放指向子串和主串的位置。操作如图所示
-
插入子串
如果插入子串长度会越界,则把原来的尾部挤出字符串范围,先从字符串尾部开始遍历后挪,当控制要插入的位置后将要插入的子串赋值给空位。
-
删除子串
判断输入的位置和长度,将删除的字符串后面的字符往前挪。
————————————————————————————————————————————
实现代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #define OK 1 5 #define ERROR 0 6 #define TRUE 1 7 #define FALSE 0 8 #define OVERFLOW -2 9 typedef int Status; 10 #define MAXSTRLEN 40 //在255范围内定义最大串长(255为1个字节) 11 typedef char SString[MAXSTRLEN + 1]; //位置0存放串的长度 12 /*********************************************************/ 13 Status StrAssign(SString T, char *chars); //字符串赋值 14 Status StrCopy(SString T, SString S); //字符串拷贝 15 Status StrEmpty(SString S); //字符串判空 16 Status StrLength(SString S); //返回字符串长度 17 Status StrPrint(SString T); //打印字符串 18 Status ClearString(SString S); //清空字符串 19 Status Concat(SString T, SString S1, SString S2); //字符串联结 20 Status Index(SString T, SString S); //索引子串位置 21 Status StrInsert(SString T, SString S, int pos); //插入子串 22 Status StrDelete(SString S, int pos, int len); //删除某个位置长度为len的子串 23 /*自己写的方法,传入两个字符串进行比较,如果完全匹配则相同,不完全匹配则判断是否为子串*/ 24 Status StrCompare(SString T, SString S); //字符串比较 25 Status StrSubString(SString longStr, SString shortStr); //匹配子串 26 /*********************************************************/ 27 int main() 28 { 29 SString S1, S2, S3, S4, T; 30 char str[MAXSTRLEN]; 31 int pos, len; 32 printf("Input S1:"); 33 gets(str); //scanf无法读取到空格 34 printf("----------------------------------\n"); 35 StrAssign(S1, str);//将输入的str赋值给串S1 36 printf("str[40]:%s\n", str); 37 StrPrint(S1); 38 printf("Length:%d\n", StrLength(S1)); 39 // printf("S1:%s\n", S1 + 1); //跳过S1[0]打印 40 printf("----------------------------------\n"); 41 StrCopy(S2, S1); 42 printf("StrCopy... OK.\n"); 43 printf("S2:"); 44 StrPrint(S2); 45 printf("S2.len:%d\n", StrLength(S2)); 46 printf("----------------------------------\n"); 47 ClearString(S2); 48 StrEmpty(S2); 49 printf("----------------------------------\n"); 50 printf("Input S3:"); 51 gets(str); 52 StrAssign(S3, str); 53 printf("StrCompare... OK.\n"); 54 StrCompare(S3, S1); 55 printf("----------------------------------\n"); 56 Concat(S4, S1, S3); 57 printf("Concat... OK.\n"); 58 printf("S4:"); 59 StrPrint(S4); 60 printf("Length:%d\n", StrLength(S4)); 61 printf("----------------------------------\n"); 62 printf("Index S4... OK.\n"); 63 printf("Input index str:"); 64 gets(str); 65 StrAssign(T, str); 66 Index(T, S4); 67 printf("----------------------------------\n"); 68 printf("Input Position:"); 69 scanf("%d", &pos); 70 printf("Insert str to S4... OK.\n"); 71 StrInsert(T, S4, pos); 72 printf("S4:"); 73 StrPrint(S4); 74 printf("Length:%d\n", StrLength(S4)); 75 printf("----------------------------------\n"); 76 printf("Input Position and Length:"); 77 scanf("%d %d", &pos, &len); 78 StrDelete(S4, pos, len); 79 printf("S4:"); 80 StrPrint(S4); 81 printf("Length:%d\n", StrLength(S4)); 82 return 0; 83 } 84 /* 字符串赋值,当赋值字符串长度超过被赋值字符串时候截断,未超过时先将长度存入T[0],再逐位赋值 */ 85 Status StrAssign(SString T, char *chars) 86 { 87 int i; 88 if (strlen(chars) > MAXSTRLEN) 89 { 90 for (i = 1; i <= MAXSTRLEN; ++i) 91 T[i] = *(chars + i - 1); 92 T[0] = MAXSTRLEN; 93 } 94 else 95 { 96 T[0] = strlen(chars); //p.s.此时T[0]存入的是int类型的数据,打印%s时无法显示 97 for (i = 1; i <= MAXSTRLEN; ++i) 98 T[i] = *(chars + i - 1); 99 return OK; 100 } 101 } 102 /* 字符串拷贝,逐个字符拷贝(仅拷贝长度范围内的) */ 103 Status StrCopy(SString T, SString S) 104 { 105 int i; 106 //p.s.此处要拷贝长度+1,将S1的\0同时拷贝进去,否则T中没有\0 107 for (i = 1; i <= S[0]; ++i) 108 T[i] = S[i]; 109 T[0] = S[0]; 110 return OK; 111 } 112 /* 字符串判空,当S[0]==0时为空 */ 113 Status StrEmpty(SString S) 114 { 115 if (S[0] == 0) 116 { 117 printf("String is Empty\n"); 118 return TRUE; 119 } 120 else 121 { 122 printf("String is not Empty\n"); 123 return FALSE; 124 } 125 } 126 /* 返回子串长度 */ 127 Status StrLength (SString S) 128 { 129 return S[0]; 130 } 131 /* 打印字符串 */ 132 Status StrPrint(SString T) 133 { 134 int i; 135 for (i = 1; i <= T[0]; ++i) 136 { 137 printf("%c", T[i]); 138 } 139 printf("\n"); 140 return OK; 141 } 142 /* 清空字符串 */ 143 Status ClearString(SString S) 144 { 145 S[0] = 0; 146 return OK; 147 } 148 /* 字符串联接,通过T来存储结果,S2连接而成的新串,若未截断则返回TRUE,截断返回FAlSE,注意字符串数组越界问题 */ 149 Status Concat(SString T, SString S1, SString S2) 150 { 151 int i; 152 if (S1[0] + S2[0] <= MAXSTRLEN) 153 { 154 for (i = 1; i <= S1[0]; ++i) 155 T[i] = S1[i]; 156 for (i = 1; i <= S2[0]; ++i) 157 T[i + S1[0]] = S2[i]; 158 T[0] = S1[0] + S2[0]; 159 return TRUE; 160 } 161 else //先存完S1中的,再存S2中的内容,条件是不能越界 162 { 163 for (i = 1; i <= S1[0] && i <= MAXSTRLEN - 1; ++i) 164 T[i] = S1[i]; 165 for (i = 1; i <= MAXSTRLEN - S1[0]; ++i) 166 T[i + S1[0]] = S2[i]; 167 T[0] = MAXSTRLEN; 168 return FALSE; 169 } 170 } 171 /* 索引子串 */ 172 Status Index(SString T, SString S) 173 { 174 int i = 1, j = 1; 175 while(j <= T[0] && i <= S[0]) 176 { 177 if (T[j] == S[i]) 178 { 179 ++i; 180 ++j; 181 } 182 else 183 { 184 i = i - j + 2; 185 j = 1; 186 } 187 } 188 if (j > T[0]) 189 { 190 printf("Position:%d\n", i - j + 1); 191 return OK; 192 } 193 else 194 { 195 printf("substring is not exist\n"); 196 return ERROR; 197 } 198 } 199 /* 在位置pos处插入子串T */ 200 Status StrInsert(SString T, SString S, int pos) 201 { 202 int i; 203 if (pos > S[0]) 204 pos = S[0] + 1; 205 if (S[0] + T[0] <= MAXSTRLEN) 206 { 207 for (i = S[0] + T[0]; i >= pos + T[0]; --i) 208 S[i] = S[i - T[0]]; 209 for (i = 1; i <= T[0]; ++i) 210 S[pos + i - 1] = T[i]; 211 S[0] = S[0] + T[0]; 212 return OK; 213 } 214 else 215 { 216 for (i = MAXSTRLEN; i >= pos + T[0]; --i) 217 S[i] = S[i - T[0]]; 218 for (i = 1; i <= T[0]; ++i) 219 S[pos + i - 1] = T[i]; 220 S[0] = MAXSTRLEN; 221 return ERROR; 222 } 223 } 224 Status StrDelete(SString S, int pos, int len) 225 { 226 int i; 227 if (pos > S[0]) 228 return ERROR; 229 else if (pos + len > S[0]) 230 len = S[0] - pos + 1; 231 for (i = pos + len; i <= S[0]; ++i) 232 S[i - len] = S[i]; 233 S[0] -= len; 234 } 235 /* 字符串比较。比较字符串是否完全相同,如果不同则判断子串所在的位置 */ 236 Status StrCompare(SString T, SString S) 237 { 238 int i, j; 239 /* 当两个字符串长度相同时,逐个判断字符是否相同,不相同则退出,相同则继续比较 */ 240 if (T[0] == S[0]) 241 { 242 for (i = 1; i <= S[0]; ++i) 243 { 244 if (T[i] != S[i]) 245 { 246 printf("A.len==B.len , A!=B \n"); 247 return ERROR; 248 } 249 } 250 printf("A == B\n"); 251 return OK; 252 } 253 else if(T[0] < S[0]) 254 StrSubString(T, S); 255 else if(T[0] > S[0]) 256 StrSubString(S, T); 257 } 258 /* 判断A是否是B的子串。逐个遍历长字符串,当短字符串首字符与长字符串字符相同时,短字符串与长字符串逐个比较,中途有不匹配的情况则重新开始比较,长字符串继续遍历,如果短字符串比对完并且最后一个字符也相同时则是子串 */ 259 Status StrSubString(SString shortStr, SString longStr) 260 { 261 int i, j = 1; 262 for (i = 1; i <= longStr[0]; ++i) 263 { 264 if (shortStr[1] == longStr[i]) 265 { 266 for (j = 1; j <= shortStr[0] ; ++j) 267 { 268 if (j == shortStr[0] && shortStr[j] == longStr[j + i - 1]) 269 { 270 printf("A is substring of B.Location is:%d\n", i); 271 return OK; 272 } 273 if (shortStr[j] != longStr[j + i - 1]) 274 break; 275 } 276 } 277 } 278 printf("A not substring of B\n"); 279 return ERROR; 280 }