CSP-201903-2-二十四点
一、中缀表达式转后缀表达式
中缀表达式是一种常见的数学表达式书写方式,其中操作符位于相关的操作数之间,如 A + B
。而后缀表达式(逆波兰表示法)则是一种没有括号,操作符跟随操作数之后的表示方法,例如相同的表达式在后缀表示法中写作 A B +
。
转换过程通常使用一个栈来临时存储操作符,以保持操作符的正确顺序和处理优先级。以下是转换步骤:
- 创建一个空栈用于存放操作符,创建一个空列表用于输出后缀表达式。
- 从左到右扫描中缀表达式。
- 如果遇到操作数,则直接将其加到输出列表。
- 如果遇到左括号
(
,则将其压入栈中。 - 如果遇到右括号
)
,则从栈中弹出操作符并加到输出列表,直到遇到左括号为止(左括号弹出栈但不加到输出列表)。 - 如果遇到操作符,则:
- 从栈中弹出所有优先级大于或等于当前操作符的操作符,并将它们加到输出列表。
- 然后将当前操作符压入栈中。
- 扫描完毕后,将栈中剩余的操作符依次弹出并加到输出列表的末尾。
- 最终,输出列表就是转换得到的后缀表达式。
二、计算后缀表达式的结果
计算后缀表达式(逆波兰表示法)的结果也需要使用一个栈。以下是计算步骤:
- 创建一个空栈用于存放操作数。
- 从左到右扫描后缀表达式。
- 如果遇到操作数,则将其压入栈中。
- 如果遇到操作符,则从栈中弹出顶部的两个操作数(注意弹出的顺序),对它们应用操作符进行计算,然后将结果压回栈中。
- 重复上述过程,直到后缀表达式的末端。
- 表达式结束时,栈顶的元素即为整个表达式的计算结果。
三、举例
例子1:
中缀表达式: 3 + 4 * 2 / ( 1 - 5 )
后缀表达式: 3 4 2 * 1 5 - / +
例子2:
中缀表达式: (( 7 + 3 ) * ( 5 - 2 )) / ( 8 - 4 )
后缀表达式: 7 3 + 5 2 - * 8 4 - /
例子3:
中缀表达式: 8 + 3 * 4 / 2
后缀表达式: 8 3 4 * 2 / +
四、代码
#include <iostream>
#include <stack>
#include <string>
#include <vector>
#include <sstream>
#include <cctype>using namespace std;// 检查是否为操作符
bool isOperator(char c) {return c == '+' || c == '-' || c == 'x' || c == '/';
}// 比较操作符优先级
int precedence(char op) {if (op == '+' || op == '-') return 1;if (op == 'x' || op == '/') return 2;return 0;
}// 中缀表达式转后缀表达式
string infixToPostfix(const string& infix) {stack<char> opStack;string postfix;for (char c : infix) {if (isdigit(c)) {postfix += c;}else if (c == '(') {opStack.push(c);}else if (c == ')') {while (!opStack.empty() && opStack.top() != '(') {postfix += opStack.top();opStack.pop();}opStack.pop(); // 弹出 '('}else if (isOperator(c)) {while (!opStack.empty() && precedence(opStack.top()) >= precedence(c)) {postfix += opStack.top();opStack.pop();}opStack.push(c);}}while (!opStack.empty()) {postfix += opStack.top();opStack.pop();}return postfix;
}// 计算后缀表达式
int evaluatePostfix(const string& postfix) {stack<int> valStack;for (char c : postfix) {if (isdigit(c)) {valStack.push(c - '0');}else {int val2 = valStack.top(); valStack.pop();int val1 = valStack.top(); valStack.pop();switch (c) {case '+': valStack.push(val1 + val2); break;case '-': valStack.push(val1 - val2); break;case 'x': valStack.push(val1 * val2); break;case '/': valStack.push(val1 / val2); break;}}}return valStack.top();
}int main()
{int n;cin >> n;for (int i = 0; i < n; i++){string infix;cin >> infix;string postfix = infixToPostfix(infix);int result = evaluatePostfix(postfix);if (result == 24){cout << "Yes\n";}else{cout << "No\n";}}return 0;
}