怎么实现Linux下的逆波兰计算器dc?
2014-01-12 22:41
639 查看
#返回上一级
@Author: 张海拔
@Update: 2014-01-12
@Link: http://www.cnblogs.com/zhanghaiba/p/3516660.html
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*)来放回一个字符到缓冲区。
#返回上一级
@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 = 0; //point to next empty space //public form main.h int token(); //public form main.c char buf[BUF_SIZE]; int cnt = 0; int main(void) { int c; int op2, op1; while ((c = token()) != EOF) { switch(c) { case NUM: push(atoi(buf)); break; case '+': if (size() >= 2) { op2 = pop(), op1 = pop(); push(op1 + op2); } else printf("dc: stack empty\n"); break; case '-': if (size() >= 2) { op2 = pop(), op1 = pop(); push(op1 - op2); } else printf("dc: stack empty\n"); break; case '*': if (size() >= 2) { op2 = pop(), op1 = pop(); push(op1 * op2); } else printf("dc: stack empty\n"); break; case '/': if (size() >= 2) { 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 0; } 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 = 0; 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-1]; } int is_full() { return sp >= ST_LEN; } int is_empty() { return sp <= 0; } int size() { return sp; } void clear() { sp = 0; }
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*)来放回一个字符到缓冲区。
#返回上一级
相关文章推荐
- 05-Linux-文件基本操作管理
- Debugging Portal for linux
- Linux命令详解之序
- PrintkTimes for linux
- LINUX TOP,不是这样玩地!!!
- centos6.3环境下安装openoffice及报错处理方法
- CentOS 开机显示"no native mode , forcing panel scaling" 的解决方法,亲测有效!
- 我一向觉得做软件的人不像我们做硬件的人大气,果然这样
- CentOS postfix无法启动——mysql-libs未安装
- Linux 查看某个用户组下面的所有用户
- Linux du命令学习
- Linux df命令学习
- Linux sed命令学习
- Linux crontab命令学习
- linux lcd设备驱动剖析三
- Centos 6.3 添加中文输入法
- linux lcd设备驱动剖析二
- linux下录屏工具
- linux下getrusage()
- Linux版本