行文本编辑算法思想(堆栈)!

来源:互联网 发布:大学生跑步软件 编辑:程序博客网 时间:2024/05/16 15:06

问题:在本文内输入一段字符,计算机不可能直接就将用户输入的字符写入文本,肯定要先建立一个缓存区,待用户修改完毕后,再写入。假设当用户输入abcde时发现多写了一个e,继续输入退格(#)。。。等等。利用堆栈即可实现。

 

算法:假设这里只处理两种特殊的字符,退格字符#和清除上一行字符@,那么只需要将除上述两个字符以外的其他字符依次入栈,当接收到#字符时则出栈一个元素(即相当于删除一个),当接收到@字符时则将栈清空,依次这么循环。但需要注意,这样的循环是建立在文本指针没到EOF和'\n'的情况下,当这个循环完成后,说明指针到了EOF或者说用户输入了换行符,而无论如何都得先在文本内写入这个'\n'(在DOS中输入回车后上一行是不能改的,说明用户确定了此次输入),再次判断是否到EOF,若是结束,若不是则继续循环。内循环外主要是处理一下出现回车符的情况,避免用户已经换行了而输入一个@后直接被全删除了这种BUG。

#include <stdio.h>#include <malloc.h>#include <process.h>#define S_SIZE 100   //栈的空间大小#define STACKINCREAMENT 10//增加空间struct SqStack{int *base; //栈底int *top;  //栈顶int stacksize;   //栈当前的存储空间};FILE *fp;//全局文件指针void main(){//子函数声明void InitStack(SqStack &S);//初始化空栈void push(SqStack &S,int e);//进栈    void pop(SqStack &S,int &e);//出栈void clearstack(SqStack &S);        //清空栈void destroystack(SqStack &S);      //销毁栈    int StackEmpty(SqStack S);         //判空void LineEdit();//主函数开始    fp=fopen("test.txt","w");if(fp){   LineEdit();fclose(fp);printf("写入成功,请查看!");}elseprintf("写入失败!");}void InitStack(SqStack &S){S.base=(int *)malloc(S_SIZE*sizeof(int));S.stacksize=S_SIZE;S.top=S.base;//初始化空栈}void push(SqStack &S,int e){//进栈if(S.top-S.base>=S.stacksize){S.base=(int *)realloc(S.base,(S.stacksize+STACKINCREAMENT)*sizeof(int));S.top=S.base+S.stacksize;S.stacksize+=STACKINCREAMENT;}*(S.top)=e;S.top++;  }void pop(SqStack &S,int &e){//出栈if(S.base!=S.top){S.top--;e=*S.top;}}void clearstack(SqStack &S){S.top=S.base;}//清空栈void destroystack(SqStack &S){free(S.base);//销毁指针,释放内存 S.base=NULL; S.top=NULL; S.stacksize=0;}int StackEmpty(SqStack S){if(S.base==S.top)return 1;elsereturn 0;}void LineEdit(){SqStack s;char ch;int e;InitStack(s);printf("请输入一段文本以^Z作为结束:\n");ch=getchar();while(ch!=EOF){while(ch!=EOF && ch!='\n'){switch(ch){case '#':if(!StackEmpty(s)) pop(s,e);break;  //弹出一个case '@':clearstack(s);break;   //清空一行default :push(s,ch);//其他字符则入栈}ch=getchar();}//将当前栈中所有元素写入文本//上面的循环结束说明要么到了文本结尾,要么有换行字符while(s.base<s.top){fputc(*s.base++,fp);}fputc('\n',fp);clearstack(s);if(ch!=EOF)ch=getchar();}}