经典的表达式求值问题
来源:互联网 发布:非线性最优化试题 编辑:程序博客网 时间:2024/04/28 02:54
这是一个acm练习题,总是觉得自己练习的太少了,这么简单的题目都不会,弄了这么久,估计是不适合编程吧,想想都好气啊!
进入正题,题目如下:
**表达式求值
时间限制: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**
思路:反正总得先把中缀表达式换成后缀表达式,在这引用一个哥们的中缀转后缀的博客,也忘了是谁的了,如下:** 中缀表达式转后缀表达式的方法:
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
6.最终将栈中的元素依次出栈,输出。
例如
a+b*c+(d*e+f)g —-> abc+de*f+g*+
遇到a:直接输出: 后缀表达式:a 堆栈:空 遇到+:堆栈:空,所以+入栈 后缀表达式:a 堆栈:+ 遇到b: 直接输出 后缀表达式:ab 堆栈:+ 遇到*:堆栈非空,但是+的优先级不高于*,所以*入栈 后缀表达式: ab 堆栈:*+ 遇到c:直接输出 后缀表达式:abc 堆栈:*+ 遇到+:堆栈非空,堆栈中的*优先级大于+,输出并出栈,堆栈中的+优先级等于+,输出并出栈,然后再将该运算符(+)入栈 后缀表达式:abc*+ 堆栈:+ 遇到(:直接入栈 后缀表达式:abc*+ 堆栈:(+ 遇到d:输出 后缀表达式:abc*+d 堆栈:(+ 遇到*:堆栈非空,堆栈中的(优先级小于*,所以不出栈 后缀表达式:abc*+d 堆栈:*(+ 遇到e:输出 后缀表达式:abc*+de 堆栈:*(+ 遇到+:由于*的优先级大于+,输出并出栈,但是(的优先级低于+,所以将*出栈,+入栈 后缀表达式:abc*+de* 堆栈:+(+ 遇到f:输出 后缀表达式:abc*+de*f 堆栈:+(+ 遇到):执行出栈并输出元素,直到弹出左括号,所括号不输出 后缀表达式:abc*+de*f+ 堆栈:+ 遇到*:堆栈为空,入栈 后缀表达式: abc*+de*f+ 堆栈:*+ 遇到g:输出 后缀表达式:abc*+de*f+g 堆栈:*+ 遇到中缀表达式结束:弹出所有的运算符并输出 后缀表达式:abc*+de*f+g*+ 堆栈:空
**
用这个思路,转成后缀表达式求值,后缀表达式不多赘述,直接上代码:
#include <stack>#include <stdio.h>#include <ctype.h>#include <string.h>#include <stdlib.h>using namespace std;int priority(char c){ if(c == '=') return 0; if(c == '+') return 1; if(c == '-') return 1; if(c == '*') return 2; if(c == '/') return 2; return 0;}void compute(stack<double>& Num,stack<char>& Op){ double b = Num.top(); Num.pop(); double a = Num.top(); Num.pop(); switch(Op.top()) { case '+':Num.push(a+b);break; case '-':Num.push(a-b);break; case '*':Num.push(a*b);break; case '/':Num.push(a/b);break; } Op.pop(); }int main(){ int z; char str[1005]; stack<double> Num; stack<char> Op; scanf("%d",&z); while(z--) { scanf("%s",str); int len = strlen(str); for(int i=0;i<len;i++) { if(isdigit(str[i])) { double n = atof(&str[i]); while(i<len && (isdigit(str[i]) || str[i]=='.')) i++; i--; Num.push(n); } else { if(str[i] == '(') Op.push(str[i]); else if(str[i] == ')') { while(Op.top()!='(') compute(Num,Op); Op.pop(); } else if(Op.empty() || priority(str[i])>priority(Op.top())) Op.push(str[i]); else { while(!Op.empty() && priority(str[i])<=priority(Op.top())) compute(Num,Op); Op.push(str[i]); } } } Op.pop(); printf("%.2f\n",Num.top()); Num.pop(); } return 0;}
- 经典的表达式求值问题
- 表达式求值的经典算法
- 表达式求值的问题
- 带括号的表达式求值问题
- 基于C语言的表达式求值问题
- 经典算法-算术表达式求值
- 经典算法-算术表达式求值
- 经典算法-算术表达式求值
- 经典算法-算术表达式求值
- 堆栈经典应用-表达式求值
- 【经典算法】-算术表达式求值
- 栈的经典应用之一——表达式求值
- 用java编写栈的经典应用-表达式求值
- 表达式求值问题
- 表达式求值问题
- 表达式求值问题
- 中缀表达式求值问题
- 中缀表达式求值问题
- Python基础-起始篇
- Swift之集合
- Android运行原理及运行机制知识汇总
- Problem H: STL——表达式求值
- Java 实例
- 经典的表达式求值问题
- 2017/06/05 Python 相关概念(二)
- python网络编程之UDP
- 关于xmlhttprequest的readystate属性的五个状态
- Problem I: STL——括号匹配
- 51nod 1469 淋漓尽致子串
- C++
- 基本数据类型所占字节数
- Problem J: STL——字典