郁闷的C小加(三)(nyoj 409)
2014-03-15 14:26
337 查看
郁闷的C小加(三)
时间限制:1000 ms | 内存限制:65535 KB难度:4
描述聪明的你帮助C小加解决了中缀表达式到后缀表达式的转换(详情请参考“郁闷的C小加(一)”),C小加很高兴。但C小加是个爱思考的人,他又想通过这种方法计算一个表达式的值。即先把表达式转换为前缀和后缀表达式,再求值。这时又要考虑操作数是小数和多位数的情况。
输入第一行输入一个整数T,共有T组测试数据(T<10)。
每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数并且小于1000000。
数据保证除数不会为0。
输出对于每组测试数据输出结果包括三行,先输出转换后的前缀和后缀表达式,再输出计算结果,结果保留两位小数。
样例输入
2 1+2= (19+21)*3-4/5=
样例输出
+ 1 2 = 1 2 + = 3.00 - * + 19 21 3 / 4 5 = 19 21 + 3 * 4 5 / - = 119.20
中缀转前缀:
从后往前
得到一个操作符或者操作数。
如果是操作数就输入到数组,
如果是')'压栈,
如果是'(' 栈顶出栈直到栈顶为')',然后将')'也弹出
如果是运算符,优先级大于等于栈顶元素,压栈
优先级小于栈顶元素,反复出栈,并将出栈的元素输入到数组,直到优先级大于等于栈顶元素,并将此运算符压栈
输入结束,就将栈里的元素全部出栈输入到数组,直到栈空。
中缀转后缀:
从前往后
得到一个操作符或者操作数。
如果是操作数就输入到数组,
如果是'('压栈,
如果是')' 栈顶出栈直到栈顶为'(',然后将'('也弹出
如果是运算符,优先级大于栈顶元素,压栈
优先级小于等于栈顶元素,反复出栈,并将出栈的元素输入到数组,直到优先级大于栈顶元素,并将此运算符压栈
输入结束,就将栈里的元素全部出栈输入到数组,直到栈空。
#include <stdio.h> #include <string.h> #include <ctype.h> #include <math.h> #include <stack> using namespace std; char a[1010], b[1010], c[1010];//b后缀,c前缀 int k = 0; stack<char> s; stack<double> num; int first(char ch) {//优先级 switch(ch) { case '+': case '-': return 1; case '*': case '/': return 2; default: return 0; } } void change1() {//中缀转前缀 int i, len = strlen(a); char t; s.push('#'); c[k ++] = '='; for(i = len - 2; i>= 0;) { if(isdigit(a[i]) || a[i] == '.') { c[k ++] = ' '; while(isdigit(a[i]) || a[i] == '.') { c[k ++] = a[i]; i --; } } else if(a[i] == ')') { s.push(a[i]); i --; } else if(a[i] == '(') { t = s.top(); while(t != ')') { c[k ++] = ' '; c[k ++] = t; s.pop(); t = s.top(); } s.pop(); i --; } else { t = s.top(); while(first(a[i]) < first(t)) { c[k ++] = ' '; c[k ++] = t; s.pop(); t = s.top(); } s.push(a[i]); i --; } } t = s.top(); while(t != '#') { c[k ++] = ' '; c[k ++] = t; s.pop(); t = s.top(); } c[k ++] = '\0'; } void change2() {//中缀转换为后缀 int len = strlen(a); int i; s.push('#'); for(i = 0; i < len - 1;) { if(isdigit(a[i]) || a[i] == '.') { while(isdigit(a[i]) || a[i] == '.') { b[k ++] = a[i]; i++; } b[k ++] = ' '; } else if(a[i] == '(') { s.push(a[i]); i++; } else if(a[i] == ')') { while(s.top() != '(') { b[k ++] = s.top(); s.pop(); b[k ++] = ' '; } s.pop(); i++; } else { char t = s.top(); while(first(t) >= first(a[i])) { b[k ++] = t; b[k ++] = ' '; s.pop(); t = s.top(); } s.push(a[i]); i++; } } char t = s.top(); while(t != '#') { b[k ++] = t; s.pop(); b[k ++] = ' '; t = s.top(); } b[k ++] = '='; b[k ++] = '\0'; } void g(char x) {//计算 double a = num.top(); num.pop(); double b = num.top(); num.pop(); switch(x) { case'+': num.push(a + b); break; case'-': num.push(b - a); break; case'*': num.push(a * b); break; case'/': num.push(b / a); break; } } void count() {//根据后缀式计算 int i, len = strlen(b); double temp = 0; for(i = 0; i < len - 1; ) { if(isdigit(b[i]) || b[i] == '.') { int f = 0; while(isdigit(b[i]) || b[i] == '.') { if(isdigit(b[i])) { temp = temp * 10 + (b[i] - '0'); if(f != 0) f ++; } else f = 1; i++; } if(f != 0) temp = temp / pow(10, f - 1); //printf("%lf\n", temp); num.push(temp); temp = 0; } else if(b[i] == ' ') { i++; } else { g(b[i]); i++; } } } int main (void) { int n, i; scanf("%d", &n); while(n --) { scanf("%s", a); change1(); k = 0; change2(); count(); for(i = strlen(c) - 1; i >= 0; i--) { printf("%c", c[i]); } printf("\n"); printf("%s\n", b); printf("%.2lf\n", num.top()); num.pop(); k = 0; } return 0; }
相关文章推荐
- nyoj 409——郁闷的C小加(三)——————【中缀式化前缀后缀并求值】
- nyoj 题目409 郁闷的C小加(三)
- nyoj-409 郁闷的C小加(三) (表达式求值,中缀式转前缀式,中缀式转后缀式)
- NYOJ 409 郁闷的C小加(三)
- NYOJ 409 郁闷的C小加(三)
- NYOJ 409 郁闷的C小加(三)
- nyoj-257 郁闷的C小加(一) 前缀表达式变后缀
- NYOJ--郁闷的C小加(三)
- NYOJ 257 郁闷的C小加(一)(栈和队列)(计算器)
- nyoj-257-郁闷的C小加(一 )中缀式变后缀式
- nyoj_257郁闷的c小加(一)
- NYOJ 257 郁闷的C小加(一)
- nyoj267郁闷的c小加 中缀表达式转后缀求值
- NYOJ 257 郁闷的C小加(一) (栈 、中缀转后缀)
- NYOJ 257 郁闷的C小加(一)
- nyoj 467 中缀式变后缀式 nyoj 257 郁闷的C小加(一)
- NYOJ 257 郁闷的C小加(一)
- nyoj_257 郁闷的c小加
- NYOJ - 郁闷的C小加(一)
- NYOJ 267 郁闷的C小加(二)