怎么实现Linux下的逆波兰计算器dc?
@Author: 张海拔
@Update: 2014-01-12
@Link: http://www.cnblogs.com/zhanghaiba/p/3516660.html
/*
*Author: ZhangHaiba
*Date: 2014-1-12
*File: dc_linux.c
*
*a demo shows how to use a stack to implement dc which as a built-in tool in Linux
*but, this demo only support int number and int operation + - * /
*/ #include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define ST_LEN 1024 //the depth of stack
#define BUF_SIZE 32
#define NUM '0' //public from stack.h
void push(int);
int pop();
int top();
int is_empty();
int is_full();
void clear();
//private form stack.c
int stack[ST_LEN];
int sp = ; //point to next empty space //public form main.h
int token();
//public form main.c
char buf[BUF_SIZE];
int cnt = ; int main(void)
{
int c;
int op2, op1; while ((c = token()) != EOF) {
switch(c) {
case NUM:
push(atoi(buf));
break;
case '+':
if (size() >= ) {
op2 = pop(), op1 = pop();
push(op1 + op2);
} else
printf("dc: stack empty\n");
break;
case '-':
if (size() >= ) {
op2 = pop(), op1 = pop();
push(op1 - op2);
} else
printf("dc: stack empty\n");
break;
case '*':
if (size() >= ) {
op2 = pop(), op1 = pop();
push(op1 * op2);
} else
printf("dc: stack empty\n");
break;
case '/':
if (size() >= ) {
op2 = pop(), op1 = pop();
push(op1 / op2);
} else
printf("dc: stack empty\n");
break;
case 'p':
printf(is_empty() ? "dc: stack empty\n" : "%d\n", top());
default:
break;
}
}
return ;
} int token()
{
int c = getchar();
if (isdigit(c)) {
buf[cnt++] = c;
while ((c = getchar()) != EOF) {
if (isdigit(c))
buf[cnt++] = c;
else {
buf[cnt] = '\0';
cnt = ;
ungetc(c, stdin);
return NUM;
}
}
} else
return c;
} void push(int item)
{
if (!is_full())
stack[sp++] = item;
} int pop()
{
if (!is_empty())
return stack[--sp];
} int top()
{
if (!is_empty())
return stack[sp-];
} int is_full()
{
return sp >= ST_LEN;
} int is_empty()
{
return sp <= ;
} int size()
{
return sp;
} void clear()
{
sp = ;
}
Linux下有一个很强大计算器bc,而逆波兰计算器dc就是bc的后台。
逆波兰表达式(后缀表达式)不需要括号也不需要定义优先级就可以运算,dc就是用来处理这种“干净”的输入。
学习了栈这个数据结构,对于逆波兰表达式的计算是很容易的。
规则是:遇到操作数则压栈,遇到操作符则弹栈,先后弹出两个操作数,第一个是op2,第二是op1,然后根据操作符把计算结果再次压栈。所以栈顶值就是当前计算的结果。
这里的实现的简易dc,仅仅支持int整型,和int操作符+ - * /。
dc的用例如下(上述实现的简易版 dc,其测试用例同下):
432 13 * p
5616
3 p
3
* p
16848
* p
dc: stack empty
16848
42 / 4 p
4
p
4
上面的实现中,需要注意的是:
(1)数据封装方面,最好把stack做成一个单独模块,这样可以提供接口,隐藏stack数据本身。
(2)对于栈中元素<2时遇到操作符,不要执行单独一次的弹栈(即把两次弹栈看做一个原子操作,测试发现dc就是这样处理的)。
(3)由于输入数字不一定是一位数,所以需要一个buffer数组来存储多位数的字符表示并封装成字符串用标准库函数atoi转换,这个过程需要用ungetc(int, FILE*)来放回一个字符到缓冲区。
怎么实现Linux下的逆波兰计算器dc?的更多相关文章
- Linux下的实用工具——计算器bc
Linux下的实用工具——计算器 1. bc指令算加法,如图: 4. bc指令算除法(进阶),如图示,10/3之所以为3,是因为我们没有指定小数点后取几位,默认取到整数部分:而10/100之所以为 ...
- 6, java数据结构和算法: 栈的应用, 逆波兰计算器, 中缀表达式--> 后缀表达式
直接上代码: public class PolandCalculator { //栈的应用:波兰计算器: 即: 输入一个字符串,来计算结果, 比如 1+((2+3)×4)-5 结果为16 public ...
- C#数据结构与算法系列(十):逆波兰计算器——逆波兰表达式(后缀表达式)
1.介绍 后缀表达式又称逆波兰表达式,与前缀表达式相似,只是运算符位于操作数之后 2.举例说明 (3+4)*5-6对应的后缀表达式就是3 4 +5 * 6 - 3.示例 输入一个逆波兰表达式(后缀表达 ...
- 在UTF8(linux)下,逆置汉字字符串
#include <stdio.h> int main() { char c[]="我是如此热爱编程!"; ,min=,max; while(c[index]) { i ...
- bc:linux下命令行计算器
在linux下,存在一个命令行的计算器:bc.该程序一般随发行版发布. bc计算器能够执行一些基本的计算,包括+,-,×,\,%. 这些计算不经针对十进制,还可以使用二进制,八进制,十六进制,并且可以 ...
- Linux下的简单好用的计算器bc
1. 关于bc bc是随意精度计算器语言,通常在linux下当计算器用,简单好用.相当于windows下的计算器. 2. 支持的运算符 主要的数学运算: + 加法 - 减法 * 乘法 / 除法 ^ 指 ...
- HDU1237 简单的计算器 【堆】+【逆波兰式】
简单的计算器 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- HDU1237 简单计算器 【栈】+【逆波兰式】
简单计算器 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- 《linux下的计算器:bc用法入门篇》
说起电脑上的计算器,可能所有人的印象都是这样的:
随机推荐
- 十一、linux文件系统权限详解
对于文件系统权限,我们前面已经讲解了一部分,这里就不在重复了. 1.修改文件权限有两种,一种是数字.一种是字母 (chmod 的修改只能是属主或者root) 数字: 修改目录权限和目录内所有文件的权限 ...
- 【Oracle 12c】最新CUUG OCP-071考试题库(53题)
53.(12-14) choose the best answer: Examine the command to create the BOOKS table. SQL>CREATE TABL ...
- sonarLint和sonarQube
在线安装和离线装sonarLint https://blog.csdn.net/limm33/article/details/51166840 下载指定版本的sonarLint https://bin ...
- COGS1752. [BOI2007]摩基亚Mokia(CDQ,树状数组)
题目描述 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米.但其真正高科技之处在于,它能够回 ...
- Haproxy搭建Web群集
一.Haproxy与LVS LVS不支持正则处理,不能实现动静分离,对于大型网站,LVS的实施配置复杂,维护成本相对较高 Harpoxy是一款可提供高可用性,负载均衡.及基于TCP和HTTP应用的代理 ...
- SQLServer 的存储过程与java交互
一. 存储过程简介 Sql Server的存储过程是一个被命名的存储在服务器上的Transacation-Sql语句集合,是封装重复性工作的一种方法,它支持用户声明的变量.条件执行和其他强大的编程 ...
- 如何在CentOS 7上使用vsftpd(FTP)的配置文件介绍
vsftpd.conf - vsftpd的配置文件. 描述 vsftpd.conf可用于控制vsftpd行为的各个方面. 默认情况下,vsftpd在/etc/vsftpd.conf位置查找此文件. 但 ...
- D01——C语言基础学PYTHON
C语言基础学习PYTHON——基础学习D01 20180705内容纲要: 1 PYTHON介绍 2 PYTHON变量定义规则 3 PYTHON文件结构 4 PYTHON语句及语法 5 字符编码 6 ...
- JDK下载与安装、 Eclipse下载与使用的总结心得_20173311118_牛明旺
一.JDK下载与安装心得: ① 从官网http://www.oracl.com/technetwork/java上下载JDK,注意一定要同意该网站上的协议,否则下载不了(即点击“Accept Lic ...
- Python中复制、深拷贝和浅拷贝的区别
深拷贝定义(deepcopy) 在Python中,由于一切皆对象,所以任何变量都可以被引用,也即可以被赋值给任何变量.但是在Python中,给变量赋值,是区分的,一般情况下,Python中的变量赋值都 ...