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;
}