HDU1237 简单的计算器 【堆】+【逆波兰式】
2015-10-18 09:51
253 查看
简单的计算器
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 11955 Accepted Submission(s): 3896
[align=left]Problem Description[/align]
读入一个仅仅包括 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
[align=left]Input[/align]
測试输入包括若干測试用例,每一个測试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中仅仅有0时输入结束,对应的结果不要输出。
[align=left]Output[/align]
对每一个測试用例输出1行,即该表达式的值,精确到小数点后2位。
[align=left]Sample Input[/align]
1 + 2 4 + 2 * 5 - 7 / 11 0
[align=left]Sample Output[/align]
3.00 13.36
关键地方是在把中缀式转换成后缀式时要保持符号栈从顶開始严格递减。否则先出栈,再进栈。
#include <stdio.h> #include <string.h> char str[202], buf[202], sign[202]; //buf存储逆波兰式 double stack[202], a; int len, n, id, id2, id3, id4; double perform(double x, double y, char ch){ if(ch == '*') return x * y; if(ch == '/') return x / y; if(ch == '+') return x + y; return x - y; } void check(char ch){ buf[id2++] = ' '; if(ch == '*' || ch == '/'){ while(id3 && (sign[id3-1] == '*' || sign[id3-1] == '/')) buf[id2++] = sign[--id3]; sign[id3++] = ch; return; } while(id3) buf[id2++] = sign[--id3]; sign[id3++] = ch; } int main(){ while(gets(str)){ len = strlen(str); if(len == 1 && str[0] == '0') break; id = id2 = id3 = id4 = 0; for(int i = 0; i < len; ++i){ if(str[i] == ' ') continue; if(str[i] >= '0' && str[i] <= '9'){ buf[id2++] = str[i]; }else check(str[i]); } while(id3) buf[id2++] = sign[--id3]; //for(int i = 0; i < id2; ++i) putchar(buf[i]); for(int i = 0; i < id2; ++i){ if(buf[i] == ' ') continue; if(buf[i] >= '0' && buf[i] <= '9'){ sscanf(buf + i, "%lf%n", &stack[id4++], &n); i += n - 1; }else stack[id4-2] = perform(stack[id4-2], stack[id4-1], buf[i]), --id4; } printf("%.2lf\n", stack[0]); } return 0; }
2014-11-3 21:55:30更新
#include <stdio.h> #include <string.h> #define maxn 1000 char buf[maxn], out[maxn], stack[maxn]; int id, id1, ida; double A[maxn]; int level(char ch) { if(ch == '+' || ch == '-') return 1; return 2; } void check(char ch) { while(id1 && level(stack[id1-1]) >= level(ch)) { out[id++] = stack[--id1]; } stack[id1++] = ch; } double cal(double a, double b, char ch) { if(ch == '-') return a - b; if(ch == '+') return a + b; if(ch == '*') return a * b; return a / b; } int main() { int i, n; bool sign; double a; while(gets(buf)) { if(strlen(buf) == 1 && buf[0] == '0') break; id = id1 = 0; sign = 0; for(i = 0; buf[i]; ++i) { if(buf[i] == ' ') continue; if(buf[i] >= '0' && buf[i] <= '9' || buf[i] == '.') { if(sign) { out[id++] = ' '; sign = 0; } out[id++] = buf[i]; } else sign = 1, check(buf[i]); } while(id1) { out[id++] = stack[--id1]; } for(i = ida = 0; i < id; ++i) { if(out[i] == ' ') continue; if(out[i] >= '0' && out[i] <= '9' || out[i] == '.') { sscanf(out + i, "%lf%n", &a, &n); A[ida++] = a; i += n - 1; } else A[ida-2] = cal(A[ida-2], A[ida-1], out[i]), --ida; } printf("%.2lf\n", A[0]); } return 0; }
相关文章推荐
- 【UWP】批量修改图标尺寸
- Velocity优点
- UML类图关系(继承、实现、依赖、关联、聚合、组合)
- Object类的常用方法
- ListView实用指南
- Android DrawerLayout demo(抽屉菜单)
- C buffer
- 浅析angular
- JDBC-SqlServer增删改查例子
- 学习javascript的闭包,原型,和匿名函数之旅
- /bin,/sbin,/usr/sbin,/usr/bin 目录之简单区别
- ztree异步加载简单示例(struts2)
- 嵌入式软件工程师题目
- BZOJ1025[SCOI]游戏
- 如何提高编程能力
- linux内核学习准备工作-链表回顾(1)
- /bin,/sbin,/usr/sbin,/usr/bin 目录之简单区别
- 十按钮布局管理
- 启动项目出现:java.lang.NoClassDefFoundError: org/springframework/asm/ClassVisitor
- 如何使用 GRUB 2 直接从硬盘运行 ISO 文件