http://hncu.acmclub.com/index.php?app=problem_title&id=111&problem_id=1741

题目描述

一个简单的行编辑程序的功能是:接收用户从终端输入的程序或数据,并存入用户的数据区。由于用户在终端上进行输入时,不能保证不出差错,因此,若在编辑程序中,“每接收一个字符即存入用户数据区”的做法显然不是很恰当。较好的做法是,设立一个输入缓冲区,用以接收用户输入的一行字符,然后逐行存入用户数据区。允许用户输入出差错,并在发现有误时可以及时更正。例如,当用户发现刚刚键入的一个字符是错的时,可补进一个退格符“#”,以表示前一个字符无效;如果发现当前键入的行内错误较多或难以补救,则可以键入一个退行符“@”,以表示当前行中的字符均无效。例如假设从终端接收了这样的两行字符:
whil##ilr#e(s#*s)
    outcha@    putchar(*s=#++);
则实际有效的是下列两行:
while(*s)
    putchar(*s++);

为此,可设这个输入缓冲区为一个栈结构,每当从终端接收了一个字符之后先作如下判别:如果它不是退格符也不是退行符,则将该字符压入栈顶;如果是一个退格符,则从栈顶删去一个字符;如果它是一个退行符,则将字符栈清为空栈。上述处理过程可用下面算法描述之:

图:行编辑程序算法

输入格式

若干行程序或者数据,每行不超过200个字符。

输出

经过行编辑程序处理过后的输出。

样例输入

whil##ilr#e(s#*s)
outcha@ putchar(*s=#++);

样例输出

while(*s)
putchar(*s++);

#include<string.h>
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<limits.h> /* INT_MAX等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<stdlib.h> /* atoi() */
#include<math.h> /* floor(),ceil(),abs() */
/* 函数结果状态代码 */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */ #define STACK_INIT_SIZE 10 /* 存储空间初始分配量 */
#define STACKINCREMENT 2 /* 存储空间分配增量 */
typedef char SElemType; /* 定义栈元素类型为整型 */
typedef struct SqStack
{
SElemType *base; /* 在栈构造之前和销毁之后,base的值为NULL */
SElemType *top; /* 栈顶指针 */
int stacksize; /* 当前已分配的存储空间,以元素为单位 */
} SqStack; /* 顺序栈 */ Status InitStack(SqStack *S)
{
/* 构造一个空栈S */
(*S).base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!(*S).base)
exit(OVERFLOW); /* 存储分配失败 */
(*S).top=(*S).base;
(*S).stacksize=STACK_INIT_SIZE;
return OK;
} Status Push(SqStack *S,SElemType e)
{
/* 插入元素e为新的栈顶元素 */
if((*S).top-(*S).base>=(*S).stacksize) /* 栈满,追加存储空间 */
{
(*S).base=(SElemType *)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!(*S).base)
exit(OVERFLOW); /* 存储分配失败 */
(*S).top=(*S).base+(*S).stacksize;
(*S).stacksize+=STACKINCREMENT;
}
*((*S).top)++=e;
return OK;
} Status Pop(SqStack *S,SElemType *e)
{
/* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
if((*S).top==(*S).base)
return ERROR;
*e=*--(*S).top;
return OK;
} Status ClearStack(SqStack *S)
{
/* 把S置为空栈 */
(*S).top=(*S).base;
return OK;
} Status DestroyStack(SqStack *S)
{
/* 销毁栈S,S不再存在 */
free((*S).base);
(*S).base=NULL;
(*S).top=NULL;
(*S).stacksize=0;
return OK;
} Status StackTraverse(SqStack S,Status(*visit)(SElemType))
{
/* 从栈底到栈顶依次对栈中每个元素调用函数visit()。 */
/* 一旦visit()失败,则操作失败 */
while(S.top>S.base)
visit(*S.base++);
printf("\n");
return OK;
} void LineEdit() // 算法3.2
{
//利用字符栈S,从终端接收一行并传送至调用过程的数据区。
char ch, *temp;
SqStack S;
InitStack(&S); //构造空栈S
ch = getchar(); //从终端接收第一个字符
while (ch != EOF) //EOF为全文结束符
{
while (ch != EOF && ch != '\n')
{
switch (ch)
{
case '#':
Pop(&S, &ch);
break; // 仅当栈非空时退栈
case '@':
ClearStack(&S);
break; // 重置S为空栈
default:
Push(&S, ch);
break; // 有效字符进栈,未考虑栈满情形
}
ch = getchar(); // 从终端接收下一个字符
}
temp = S.base;
while (temp != S.top)
{
printf("%c", *temp);
++temp;
}
// 将从栈底到栈顶的栈内字符传送至调用过程的数据区;
ClearStack(&S); // 重置S为空栈
printf("\n");
if(ch != EOF)
{
ch = getchar(); // 读取下一行的第一个字符
}
}
DestroyStack(&S);
} int main()
{
LineEdit();
return 0;
}

HNCU1741:算法3-2:行编辑程序的更多相关文章

  1. GC算法之串行并行并发

    串行收集器: 用单线程处理所有垃圾回收工作,因为无需多线程交互,所以效率比较高.但是,也无法使用多处理器的优势,所以此收集器适合单处理器机器.当然,此收集器也可以用在小数据量(100M左右)情况下的多 ...

  2. 算法专题 | 10行代码实现的最短路算法——Bellman-ford与SPFA

    今天是算法数据结构专题的第33篇文章,我们一起来聊聊最短路问题. 最短路问题也属于图论算法之一,解决的是在一张有向图当中点与点之间的最短距离问题.最短路算法有很多,比较常用的有bellman-ford ...

  3. c语言行编辑程序

    static.h 头文件 typedef struct bufferStatic{ char *top; char *base; int staticSize; }bufferStatic; type ...

  4. 某拍sig算法揭秘---50行代码下载5000万小姐姐自拍小视频

    背景: ​ ​ ​ 首先我们需要一点点python基础,比如可以运行类似下面的代码 import requests headers={ "xxx":"xxx", ...

  5. 《串并行数据结构与算法(SML语言)实验》题解

    注意:本题解仅供参考学习,请勿直接抄袭代码,否则造成的后果和笔者无关. 第一题: 题意: 对n个数升序排序. 题解: 快排,不解释. 代码(省略了输入输出函数,下同): val n = getInt ...

  6. kmeans算法并行化的mpi程序

    用c语言写了kmeans算法的串行程序,再用mpi来写并行版的,貌似参照着串行版来写并行版,效果不是很赏心悦目~ 并行化思路: 使用主从模式.由一个节点充当主节点负责数据的划分与分配,其他节点完成本地 ...

  7. iOS应用九宫格算法

      1.框框横向间隔为:( "界面的总宽度"-"界面每行的控件的宽度" * "每行要现实的列数(这里是3)") / ("列数 + ...

  8. 用最简单的方式在C#中使用多线程加速耗时的图像处理算法的执行(多核机器)。

    图像处理中,有很多算法由于其内在的复杂性是天然的耗时大户,加之图像本身蕴涵的数据量比一般的对象就大,因此,针对这类算法,执行速度的提在很大程度上依赖于硬件的性能,现在流行的CPU都是至少2核的,稍微好 ...

  9. 数据结构算法C语言实现(七)--- 3.1栈的线性实现及应用举例

    一.简述 栈,LIFO.是操作受限的线性表,和线性表一样有两种存储表示方法.下面以顺序存储为例,实现. 二.ADT 暂无. 三.头文件 //3_1.h /** author:zhaoyu email: ...

随机推荐

  1. C#后台跳转

    后台跳转的方法: 1.js脚本 [不推荐使用] Context.Response.Write("<script language=javascript>window.locati ...

  2. JDBC_批量处理语句提高处理速度

    •当需要成批插入或者更新记录时.可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理.通常情况下比单独提交处理更有效率 •JDBC的批量处理语句包括下面两个方法: –addB ...

  3. 初识 python

    Python 语言介绍 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Python变化 python 2 和 python 3 1.1/2 等于0.5 2.print ...

  4. sql中charindex和cast结合使用

    1.CHARINDEX函数常常用来在一段字符中搜索字符或者字符串. 语法 CHARINDEX ( expression1 , expression2 [ , start_location ] ) 返回 ...

  5. Linux下同步工具inotify+rsync使用详解

    1. rsync 1.1 什么是rsync rsync是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件.它使用所谓的“Rsync演算法”来使本地和远程两个主机之间的文件达到同步,这 ...

  6. Windows Phone 8初学者开发—第14部分:在运行时绑定到真实的数据

    原文 Windows Phone 8初学者开发—第14部分:在运行时绑定到真实的数据 第14部分:在运行时绑定到真实的数据 原文地址: http://channel9.msdn.com/Series/ ...

  7. linux下观看b站视频,解决字体乱码

    如图: 各种字体都显示为方块,解决办法也很简单. 点击视频右边的齿轮,也就是设置,更改字体. 默认的微软雅黑字体,一般换成其他的字体应该都能正常显示. 这是为更改后:

  8. 16个值得个人站长做的广告联盟[转自cnzz]

    建站也有好多年了,也建了几个站,有些微波收入, 反复测试了挺多广告联盟, 下面介绍一下: 1.googleadsense联盟: 推荐指数:☆☆☆☆☆ Google广告联盟是现在信誉最好的广告提供商之一 ...

  9. 【转】解决Gradle DSL method not found: ‘android()’

    [转]解决Gradle DSL method not found: ‘android()’ 最近导入as的项目出了这样的问题 这个问题困扰了我很长时间,好吧,搜了半天全都是runProguard的,最 ...

  10. Group DataList

    一,效果图. 二,源代码. <!DOCTYPE html><html><head> <meta charset="UTF-8"> & ...