题目描述
这道题目的主要解题思想是用堆栈来解决四则运算的优先级问题。
本题的关键点在于如何正确处理运算符的优先级问题,可以使用两个栈来解决这个问题。一个是运算数栈,另一个是运算符栈。
在遍历当前算术表达式字符串时会有五种情况:
- 当前字符是数字。
如果当前字符是数字的话,那么就直接将其转换成对应的整型数并压入运算数栈中。 - 当前字符是加号
由于加法的优先级低于乘法和除法,所以不能直接进行加法运算,要先把加号压入运算符栈中。 - 当前字符是减号
减法的优先级同加法一样,也不能直接进行运算。此处为了后续操作方便,统一将a-b的形式转换成a+(-b)的形式来运算减法。即将加号压入运算符栈中,将第二个运算数取反之后压入运算数栈中。 - 当前字符是乘号
乘法在本题中是优先级最高的,可以直接进行运算。去运算数栈的栈顶元素和乘号后面的那个运算数做乘法,将结果再压入运算数栈中。 - 当前字符是除号
除法的优先级同乘法一样,操作同上。
在遍历完算术表达式时,说明式子中的乘除运算都已经完成,下面只剩下加法(减法已经转换成加法),直到运算符栈为空,最终的结果就是运算数的栈顶元素。最后拿这个数和24来进行比对即可。
#include <iostream>
#include <string>
#include <string.h>
#include <stack>
using namespace std;
//二十四点游戏 ,特别注意运算符的优先级问题!!!用堆栈来解决
int main() {
int n; //表达式的个数
string str; //暂存当前表达式
int i, j;
int result[100] = {0}; //1代表计算结果是24, 0代表不是
stack<int> num; //运算数栈
stack<char> op; //运算符栈
cin >> n;
for (i = 0; i < n; i++) {
cin >> str;
for (j = 0; j < str.length(); j++) {
if (isdigit(str[j])) { //是数字
num.push(str[j] - '0');
} else if (str[j] == '+') {
op.push('+');
} else if (str[j] == '-') { //将减法转换成加法
op.push('+');
num.push(-(str[j + 1] - '0'));
j++;
} else if (str[j] == 'x') { //直接计算乘法
int num1 = num.top();
num.pop();
num.push(num1 * (str[j + 1] - '0'));
j++;
} else if (str[j] == '/') { //直接计算除法
int num1 = num.top();
num.pop();
num.push(num1 / (str[j + 1] - '0'));
j++;
}
}
while (!op.empty()) {
int num1 = num.top();
num.pop();
int num2 = num.top();
num.pop();
num.push(num1 + num2);
op.pop();
}
if (num.top() == 24) {
result[i] = 1;
}
num.pop(); //清空操作数栈
}
for (i = 0; i < n; i++) {
if (result[i] == 0) {
cout << "No" << endl;
} else {
cout << "Yes" << endl;
}
}
return 0;
}