————————————————————————————————————————————
- 定長順序存儲表示法
————————————————————————————————————————————
存儲結構:
使用字符串數組作為存儲,定義字符串數組長度為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 }