NYOJ-35 表达式求值
2016-08-06 21:01
441 查看
表达式求值
时间限制:3000 ms | 内存限制:65535 KB难度:4
描述ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧。
比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数)
输入第一行输入一个整数n,共有n组测试数据(n<10)。
每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数。
数据保证除数不会为0
输出每组都输出该组运算式的运算结果,输出结果保留两位小数。
样例输入
2 1.000+2/4= ((1+2)*5+1)/4=
样例输出
1.50 4.00
代码:
# include <stdio.h> # include <math.h> # include <string.h> # include <stack> using namespace std; char s[1005]; stack<double> dtack; stack<char> ctack; int main(void) { int n; scanf("%d", &n); while (n--) { scanf("%s", &s[1]); int len = strlen(&s[1]); s[0] = '('; s[len] = ')'; int i; for (i = 0; i <= len; i++) { if (s[i] == '(') { ctack.push(s[i]); } else if (s[i] >= '0' && s[i] <= '9') { double v = 0.0; int spot = 0; // 用以记录小数点的位置 while (s[i] >= '0' && s[i] <= '9' || s[i] == '.') { if (s[i] == '.') { spot = i; } else { v = v * 10 + (s[i] - '0'); } i++; } i--; if (spot == 0) { dtack.push(v); } else { dtack.push(v / pow(10, (i - spot))); } } else if (s[i] == '+' || s[i] == '-') { while (ctack.top() != '(') { double a = dtack.top(); dtack.pop(); double b = dtack.top(); dtack.pop(); double c = 0.0; switch(ctack.top()) { case '+' : c = b + a; break; case '-' : c = b - a; break; case '*' : c = b * a; break; case '/' : c = b / a; break; } dtack.push(c); //把计算的结果压入栈中 ctack.pop();//弹出运算过的运算符 } ctack.push(s[i]); } else if (s[i] == '*' || s[i] == '/') { if (ctack.top() == '*') { double a = dtack.top(); dtack.pop(); double b = dtack.top(); dtack.pop(); dtack.push(b * a); ctack.pop(); } else if (ctack.top() == '/') { double a = dtack.top(); dtack.pop(); double b = dtack.top(); dtack.pop(); dtack.push(b / a); ctack.pop(); } ctack.push(s[i]); } else if (s[i] == ')') { while (ctack.top() != '(') { double a = dtack.top(); dtack.pop(); double b = dtack.top(); dtack.pop(); double c = 0.0; switch (ctack.top()) { case '+' : c = b + a; break; case '-' : c = b - a; break; case '*' : c = b * a; break; case '/' : c = b / a; break; } dtack.push(c); ctack.pop(); } ctack.pop(); } } printf("%.2lf\n", dtack.top()); dtack.pop(); } return 0; }
典型的进栈和出栈
相关文章推荐
- php trim()函数
- 跟我一起写Makefile(2)--- Makefile介绍+Makefile规则
- RecycleView从显示到下拉刷新和加载更多
- 期货的形成和发展
- MYSQL --Subquery returns more than 1 row查询结果多于一行
- leetcode No81. Search in Rotated Sorted Array II
- Windows平台下Oracle实例启动过程中日志输出
- 不敢死队问题
- 常用的mysql复制参数
- 插件开发之360 DroidPlugin源码分析(三)Binder代理
- 什么是死锁?产生的条件?如何避免?
- C++ Primer 第10章 知识点回顾
- Matrix.preTranslate和 postTranslate
- hdu Keep In Touch
- 插件开发之360 DroidPlugin源码分析(三)Binder代理
- 跟我一起写Makefile(1)--- 概述
- android开发:正确的开发一个Splash页面
- 安装Nvidia k80驱动步骤
- Ubuntu Git安装
- Javascript模块化编程(三):require.js的用法(转)