简单文本编辑器(双向链表+堆串)

  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 }

 

posted @ 2021-12-27 20:03  吕辉  阅读(86)  评论(0)    收藏  举报