文章目录
题目描述
读入一个只包含+、-、*、/ 的非负整数计算表达式,计算该表达式的值。
样例输入:
30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 *87 + 57 * 92
样例输出:
12178.21
一、思路
1.中缀表达式转后缀表达式
①设立一个操作符栈,用来临时存放操作符;设立一个数组或者队列,用以存放后缀表达式;
②从左至右扫描中缀表达式,如果碰到操作数(可能不止一位),就把操作数加入后缀表达式中;
③如果碰到了操作符op
,就将其优先级与操作符栈的栈顶操作符比较;
- 如果
op
的优先级高于栈顶操作符,则压入操作符栈; - 如果
op
的优先级低于或者等于栈顶操作符,则将操作符栈的操作符不断弹出到后缀表达式中,直到op的优先级高于栈顶操作符。
④重复上述操作,直到中缀表达式扫描完毕,之后若操作符栈仍有元素(即不为空),则将它们依次弹出至后缀表达式中。
注:操作符的优先级指的是计算的优先级,即乘法=除法>加法=减法,可以使用map
建立操作符和优先级的映射,1表示乘除优先级,0表示加减优先级。
2.计算后缀表达式
从左到右扫描后缀表达式,如果是操作数就压入栈,如果是操作符,就连续弹出两个操作数,然后进行操作符的操作,并将计算结果(即新的操作数)压入栈中。反复直到后缀表达式扫描完毕,此时栈内只有一个元素,为最终答案。
注:
- 除法可能会导致浮点数,因此操作数类型要设置为浮点型;
- 上述一切都是基于合法表达式,注意是否为非法表达式,导致操作不成功;
- 表达式中可能存在空格,使用
string
的erase
方法可以去除。
二、代码实现
#include <bits/stdc++.h>
using namespace std;
struct node {
double num;
char op;
bool flag; // true means number,false means operator
};
string str;
stack<node> s; // stack of operator
queue<node> q; // series of post-expression
map<char, int> op;
// change mid-expression to post-expression
void change() {
double num;
node tmp;
for (int i = 0; i < str.length();) {
if