描述:给定一个合法的数学表达式,计算结果并输出。
做法:1、先将中缀表达式转成后缀表达式;2、再进行后缀表达式求值。
详细过程:https://blog.csdn.net/qq_43643944/article/details/115359682
细节问题:1、栈使用STL中提供的stack容器;2、后缀表达式存放在队列中,利用STL提供的queue容器;3、运算符的优先级利用STL中的MAP来实现。4、以字符串形式读入表达式,生成后缀表达式的同时识别出每个合法的操作数或运算符,将其以结点的形式压入队列。
#include <iostream>
#include <stack>
#include <queue>
#include <map>
using namespace std;
struct node {//单个操作数或运算符
double num;//操作数
char op;//运算符
bool flag;//1为操作数,0为运算符
};
stack<node> S;//操作符栈
queue<node> Q;//后缀表达式队列
map<char, int> mp;//运算符优先级映射
void prefix_TO_postfix(string str) {//中缀转后缀
node temp;
for (int i = 0; i < str.length();) {
if (str[i] >= '0' && str[i] <= '9') { //操作数
temp.flag = 1;
temp.num = str[i++] - '0';
while (i < str.length() && str[i] >= '0' && str[i] <= '9') {//产生完整的操作数,即可能含多个位
temp.num = temp.num * 10 + (str[i++] - '0');
}
Q.push(temp);
} else if (str[i] == '(') {//左括号
temp.flag = 0;
temp.op = str[i++];
S.push(temp);
} else if (str[i] == ')') {//右括号
while (S.top().op != '(') {
Q.push(S.top());
S.pop();
}
S.pop();//左括号不加入队列
i++;
} else {//运算符
temp.flag = 0;
while (!S.empty() && (S.top().op != '(') && (mp[str[i]] <= mp[S.top().op])) {
Q.push(S.top());
S.pop();
}
temp.op = str[i];
S.push(temp);
i++;
}
}
while (!S.empty()) { //栈非空,弹出所有操作数,加入队列
Q.push(S.top());
S.pop();
}
}
double Postfix() { //后缀表达式求值
double num1, num2;
node current, result;
while (!Q.empty()) {
current = Q.front();
Q.pop();
if (current.flag == 1) S.push(current);
else {
result.flag = 1;
num2 = S.top().num;
S.pop();
num1 = S.top().num;
S.pop();
if (current.op == '+') result.num = num1 + num2;
else if (current.op == '-') result.num = num1 - num2;
else if (current.op == '*') result.num = num1 * num2;
else result.num = num1 / num2;
S.push(result);
}
}
return S.top().num;
}
int main() {
mp['*'] = 1;
mp['/'] = 1;
mp['+'] = 0;
mp['-'] = 0;
string expression;//表达式
cin >> expression;
prefix_TO_postfix(expression);
printf("%.2f", Postfix());
return 0;
}