#include <iostream>#include <stack>#include <string>#include <sstream>using namespace std;
// 将表达式字符串转换为逆波兰表达式string convertToRPN(string expression) {
stack<string> s;
for (char c : expression) {
if (c == '+') {
s.push("+" + s.top() + s.top());
s.pop();
s.pop();
} else if (c == '-') {
s.push("-" + s.top() + s.top());
s.pop();
s.pop();
} else if (c == '*') {
s.push("*" + s.top() + s.top());
s.pop();
s.pop();
} else if (c == '/') {
s.push("/(" + s.top() + s.top() + ")");
s.pop();
s.pop();
} else {
s.push(c);
}
}
return s.top();
}
// 递归求逆波兰表达式的值double evaluateRPN(string expression) {
stack<double> s;
for (char c : expression) {
if (c == '+' || c == '-' || c == '*' || c == '/') {
double b = s.top();
s.pop();
double a = s.top();
s.pop();
if (c == '+') {
s.push(a + b);
} else if (c == '-') {
s.push(a - b);
} else if (c == '*') {
s.push(a * b);
} else if (c == '/') {
s.push(a / b);
}
} else {
s.push(stod(c));
}
}
return s.top();
}
int main() {
string expression;
cout << "请输入一个算术表达式(只包含数字、加减乘除和括号):";
cin >> expression;
expression = convertToRPN(expression); // 将表达式转换为逆波兰表达式
double result = evaluateRPN(expression); // 求逆波兰表达式的值
cout << "每完成一步运算后的结果:" << endl;
stringstream ss;
ss << expression;
string token;
while (getline(ss, token, ' ')) { // 按空格分割逆波兰表达式,并逐个输出结果
cout << token << " = " << result << endl;
if (token == "+") { // 如果是加法,则进行计算并更新结果
result += evaluateRPN(token + " " + ss.str()); // 加法运算的逆波兰表达式为当前运算符和剩余逆波兰表达式的组合字符串,例如"1 2 + = 3"表示1+2=3,其中"="是赋值运算符,"="前面的"+"是加法运算符,"="后面的"3"是结果。因此,我们通过将剩余逆波兰表达式"2"与"+"连接,并计算其结果来更新当前结果。
} else if (token == "-") { // 如果是减法,则进行计算并更新结果,减法运算的逆波兰表达式与加法类似,例如"1 2 - = 1"表示1-2=-1,其中"="是赋值运算符,"="前面的"-"是减法运算符,"="后面的"-1"是结果。因此,我们通过将剩余逆波兰表达式"2"与"-"连接,并计算其结果来更新当前结果。注意,减法运算的逆波兰表达式中包含负号"-",因此需要将减数取反后进行计算。例如"1 2 - = -1"表示1-2=-1,其中"="是赋值运算符,"="前面的"-"是减法运算符,"="后面的"-1"是结果。因此,我们通过将减数取反后的加法运算来更新当前结果。