1. 程式人生 > 其它 >簡單文字編輯器(雙向連結串列+堆串)

簡單文字編輯器(雙向連結串列+堆串)

  1 #define _CRT_SECURE_NO_WARNINGS
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <string.h>
  5 
  6 typedef struct SimpleTextEditor
  7 {
  8     char* ch;
  9     int len;
 10     struct SimpleTextEditor* front;
 11     struct SimpleTextEditor* rear;
 12     int row;
13 }STE; 14 15 void Init(STE* head); 16 void Input(STE* head); 17 void Output(STE* head); 18 void Insert(STE* head); 19 void Delete(STE* head); 20 void Index(STE* head); 21 int* Get_Next(char* a); 22 int* Get_Nextval(char* a); 23 void Census(STE* head); 24 void Replace(STE* head); 25 26
int main(void) 27 { 28 int num = 0; 29 30 STE* head = (STE*)calloc(1, sizeof(STE)); 31 Init(head); 32 while (1) 33 { 34 35 printf("****************************************************************\n"); 36 printf("輸入指令序號0.結束 1.寫入(q退出) 2.插入 3.刪除 4.替換 5.查詢 6.統計:
"); 37 scanf("%d", &num); 38 getchar(); 39 switch (num) 40 { 41 default: 42 continue; 43 case 0: 44 return 0; 45 case 1: 46 Input(head); 47 Output(head); 48 break; 49 case 2: 50 Output(head); 51 Insert(head); 52 Output(head); 53 break; 54 case 3: 55 Output(head); 56 Delete(head); 57 Output(head); 58 break; 59 case 4: 60 Output(head); 61 Replace(head); 62 Output(head); 63 break; 64 case 5: 65 Output(head); 66 Index(head); 67 getchar(); 68 Output(head); 69 break; 70 case 6: 71 Output(head); 72 Census(head); 73 getchar(); 74 Output(head); 75 break; 76 } 77 } 78 return 0; 79 } 80 81 void Init(STE* head) 82 { 83 head->ch = NULL; 84 head->len = 0; 85 head->front = NULL; 86 head->rear = NULL; 87 head->row = 0; 88 } 89 90 void Input(STE* head) 91 { 92 int i = 0; 93 char ch = '\0'; 94 char a[255] = { '\0' }; 95 STE* P;//新建行結點 96 STE* T = head;//行的尾結點 97 98 system("cls"); 99 Output(head); 100 while (T->rear != NULL) 101 { 102 T = T->rear; 103 } 104 105 while(1) 106 { 107 P = (STE*)calloc(1, sizeof(STE)); 108 P->front = T; 109 P->rear = T->rear; 110 P->row = T->row + 1; 111 112 printf("%d ", P->row);//行號 113 for (i = 0; (ch = getchar()) != '\n'; i++) 114 { 115 a[i] = ch; 116 } 117 if (0 == strcmp(a, "q"))//輸入 q 結束輸入 118 { 119 free(P); 120 break; 121 } 122 123 P->len = i; 124 P->ch = (char*)calloc(P->len, sizeof(char));//給每行申請定長的記憶體空間 125 for (i = 0; i < P->len; i++) 126 { 127 P->ch[i] = a[i]; 128 a[i] = '\0'; 129 } 130 T->rear = P; 131 T = P; 132 } 133 } 134 135 void Output(STE* head) 136 { 137 int i; 138 int j; 139 STE* P = head->rear; 140 system("cls"); 141 printf("************************簡易文字編輯器**************************\n"); 142 143 for (i = 0; P != NULL; i++) 144 { 145 printf("%d ", i + 1); 146 for (j = 0; j < P->len; j++) 147 { 148 printf("%c", P->ch[j]); 149 } 150 printf("\n"); 151 P = P->rear; 152 } 153 } 154 155 void Insert(STE* head) 156 { 157 int i = 0; 158 int j = 0; 159 char a[255] = { '\0' }; 160 char ch; 161 int row; 162 int col; 163 char* temp = NULL; 164 STE* P = head; 165 166 printf("插入到第幾行的第幾個字元前(空格分隔)\n"); 167 scanf("%d%*c%d", &row, &col); 168 getchar(); 169 printf("插入內容是:"); 170 while ((ch = getchar()) != '\n') 171 { 172 a[i++] = ch; 173 } 174 175 while (P->rear != NULL) 176 { 177 P = P->rear; 178 if (P->row == row) 179 { 180 temp = (char*)calloc(P->len + strlen(a), sizeof(char)); 181 if (col <= 1)//行首插入 182 { 183 for (i = 0; a[i] != '\0'; i++) 184 { 185 temp[i] = a[i]; 186 } 187 for (j = 0; j < P->len; j++) 188 { 189 temp[i + j] = P->ch[j]; 190 } 191 } 192 else if (col > P->len)//行尾插入//bug 193 { 194 for (i = 0; i < P->len; i++) 195 { 196 temp[i] = P->ch[i]; 197 } 198 for (i = 0; a[i] != '\0'; i++) 199 { 200 temp[i + P->len] = a[i]; 201 } 202 } 203 else//行中第 col 位置插入 204 { 205 col = col - 1;//陣列下標從0開始 206 for (i = 0; i < col; i++) 207 { 208 temp[i] = P->ch[i]; 209 } 210 for (i = col; a[i - col] != '\0'; i++) 211 { 212 temp[i] = a[i - col]; 213 } 214 for (; P->ch[i - strlen(a)] != '\0'; i++) 215 { 216 temp[i] = P->ch[i - strlen(a)]; 217 } 218 } 219 P->ch = temp; 220 P->len += (int)strlen(a); 221 break; 222 } 223 } 224 225 if (P->rear == NULL && P->row != row) 226 { 227 printf("該行不存在!\n"); 228 } 229 } 230 231 void Delete(STE* head) 232 { 233 int i; 234 int row; 235 int pos; 236 int len; 237 STE* P = head->rear; 238 char* temp = NULL; 239 240 printf("從第幾行第幾個位置開始刪除幾位(空格分隔)\n"); 241 scanf("%d%*c%d%*c%d", &row, &pos, &len); 242 while (P != NULL) 243 { 244 if (P->row == row) 245 { 246 if (pos < 1 || pos > P->len || len > (P->len - pos + 1)) 247 { 248 printf("刪除引數非法!\n"); 249 return; 250 } 251 else 252 { 253 if (pos == 1 && len == P->len)//刪除整行 254 { 255 if (P->rear == NULL)//若刪除最後一行 256 { 257 P->front->rear = NULL; 258 free(P); 259 return; 260 } 261 else 262 { 263 P->front->rear = P->rear; 264 P->rear->front = P->front; 265 free(P); 266 267 P = head->rear; 268 for (i = 1; P != NULL; i++) 269 {//修改全部行號 270 P->row = i; 271 P = P->rear; 272 } 273 return; 274 } 275 } 276 277 temp = (char*)calloc(P->len - len, sizeof(char)); 278 pos = pos - 1;//陣列下標從0開始 279 for (i = 0; i < pos; i++)//刪除點之前部分 280 { 281 temp[i] = P->ch[i]; 282 } 283 for (i = pos; i < P->len; i++)//刪除後剩餘部分 284 { 285 temp[i] = P->ch[i + len]; 286 } 287 P->ch = temp; 288 P->len -= len; 289 return; 290 } 291 } 292 P = P->rear; 293 } 294 printf("該行不存在!\n"); 295 return; 296 } 297 298 int* Get_Next(char* a) 299 { 300 int j = 0; 301 int k = -1; 302 int* next = NULL; 303 int len = 0; 304 while (a[++len] != '\0');//獲得字串 a 的長度 len 305 next = (int*)calloc(len, sizeof(int)); 306 307 next[0] = -1; 308 while (j < len) 309 { 310 if (k == -1 || a[j] == a[k]) 311 { 312 j++; 313 k++; 314 next[j] = k; 315 } 316 else 317 { 318 k = next[k]; 319 } 320 } 321 return next; 322 } 323 324 int* Get_Nextval(char* a) 325 { 326 int j = 1; 327 int k = 0; 328 int len = 0; 329 int* next = Get_Next(a); 330 int* nextval; 331 while (a[++len] != '\0'); 332 nextval = (int*)calloc(len, sizeof(int)); 333 334 nextval[0] = -1; 335 while (j < len) 336 { 337 k = next[j]; 338 if (a[j] == a[k]) 339 { 340 nextval[j] = nextval[k]; 341 } 342 else 343 {//失配,說明需要滑動到失配前的位置 344 nextval[j] = next[j]; 345 } 346 j++; 347 } 348 return nextval; 349 } 350 351 void Index(STE* head) 352 { 353 int i = 0; 354 int j = 0; 355 int len = 0; 356 int count = 0;//匹配成功的次數 357 int* next = NULL; 358 int* nextval = NULL; 359 STE* P = head->rear; 360 char a[255] = { '\0' }; 361 char ch = '\0'; 362 363 printf("請輸入查詢內容:\n"); 364 while ((ch = getchar()) != '\n') 365 { 366 a[i++] = ch; 367 } 368 len = i; 369 if (0 == len) 370 { 371 printf("查詢內容不能為空"); 372 return; 373 } 374 375 next = Get_Next(a); 376 nextval = Get_Nextval(a); 377 378 while (P != NULL) 379 { 380 i = 0; 381 while (i < P->len) 382 { 383 j = 0; 384 while (i < P->len && j < len) 385 { 386 if (j == -1 || P->ch[i] == a[j]) 387 { 388 i++; 389 j++; 390 } 391 else 392 { 393 j = nextval[j]; 394 } 395 } 396 if (j == len)//匹配成功 397 { 398 count++; 399 printf("count:%d %d(%d):", count, P->row, i - len + 1); 400 for (j = 0; j < P->len; j++) 401 { 402 printf("%c", P->ch[j]); 403 } 404 printf("\n"); 405 } 406 }//該行已遍歷 407 P = P->rear; 408 }//所有行已遍歷 409 if (count == 0) 410 { 411 printf("文字中沒有 %s\n", a); 412 } 413 } 414 415 void Census(STE* head) 416 { 417 int i; 418 int alpha = 0;//英文字母數 419 int punct = 0;//標點符號數 420 int space = 0;//空格數 421 STE* P = head->rear; 422 423 while (P != NULL) 424 { 425 for (i = 0; i < P->len; i++) 426 { 427 if ('A' <= P->ch[i] && P->ch[i] <= 'Z' || 'a' <= P->ch[i] && P->ch[i] <= 'z') 428 { 429 alpha++; 430 } 431 if ( 33 <= P->ch[i] && P->ch[i] <= 47 || 432 58 <= P->ch[i] && P->ch[i] <= 64 || 433 91 <= P->ch[i] && P->ch[i] <= 96 || 434 123 <= P->ch[i] && P->ch[i] <= 126 ) 435 { 436 punct++; 437 } 438 if (P->ch[i] == ' ') 439 { 440 space++; 441 } 442 if (P->ch[i] == '\t') 443 { 444 space += 4; 445 } 446 } 447 P = P->rear; 448 } 449 printf("英文字母數:%d\t標點符號數:%d\t空格數:%d\n", alpha, punct, space); 450 } 451 452 void Replace(STE* head) 453 { 454 int i; 455 int j; 456 int row = 0; 457 int pos = 0; 458 int len = 0; 459 int len_a = 0; 460 STE* P = head->rear; 461 char* temp = NULL; 462 char a[255] = { '\0' }; 463 464 printf("在第幾行第幾位開始替換,替換幾位(空格分隔)\n"); 465 scanf("%d%*c%d%*c%d", &row, &pos, &len); 466 getchar(); 467 printf("請輸入要替換的內容\n"); 468 scanf("%s", &a); 469 len_a = (int)strlen(a); 470 while (P != NULL) 471 { 472 if (P->row == row) 473 { 474 if (pos < 1 || pos > P->len || pos + len - 1 > P->len) 475 { 476 printf("替換目標不存在"); 477 return; 478 } 479 else 480 { 481 temp = (char*)calloc(P->len - len + len_a, sizeof(char)); 482 for (i = 0; i < pos - 1; i++) 483 {//替換前部分 484 temp[i] = P->ch[i]; 485 } 486 for (j = 0; j < len_a; j++) 487 {//替換部分 488 temp[i++] = a[j]; 489 } 490 for (j = 0; j < (P->len - pos - len + 2); j++) 491 {//替換後部分 492 temp[i++] = P->ch[j + pos + len - 1]; 493 } 494 P->ch = temp; 495 P->len = i; 496 return; 497 } 498 } 499 else 500 { 501 P = P->rear; 502 } 503 } 504 printf("該行不存在!\n"); 505 }