題目描述
這道題目的主要解題思想是用堆棧來解決四則運算的優先級問題。
本題的關鍵點在於如何正確處理運算符的優先級問題,可以使用兩個棧來解決這個問題。一個是運算數棧,另一個是運算符棧。
在遍歷當前算術表達式字符串時會有五種情況:
- 當前字符是數字。
如果當前字符是數字的話,那麼就直接將其轉換成對應的整型數並壓入運算數棧中。 - 當前字符是加號
由於加法的優先級低於乘法和除法,所以不能直接進行加法運算,要先把加號壓入運算符棧中。 - 當前字符是減號
減法的優先級同加法一樣,也不能直接進行運算。此處爲了後續操作方便,統一將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;
}