解法一、遞迴
🔹 把大式子拆成小式子
依照 優先度由低而高、由後往前 的順序處理
+, -
→ *, /, %
→ (, )
當一個式子沒有任何運算符號(代表他只剩數字),返回數值
當一個式子運算完成,返回數值
例如測資 12 * 34 * 56 + 78
+
明顯需要最後處理
於是由後往前找到 +
後
將問題拆成 12 * 34 * 56
+ 78
兩個式子
先處理完這兩個式子後再處理加法
遞迴的代碼大概長做這樣
calculate(int begin, int end){
// ...
return calculate(int begin1, int end1) + calculate(int begin2, int end2);
// ...
return calculate(int begin1, int end1) * calculate(int begin2, int end2);
// ...
return num;
}
完整的步驟是 (中括號代表式子的拆法)
- 拆
+
號:[12 * 34 * 56] + [78]
- 拆
/
號:[[12 * 34] * 56] + [78]
- 拆
*
號:[[12 * 34] * 56] + [78]
- 返回結果:
22926
另外由於括號要最後處理
因此需要一個變數 layer
紀錄當前位置括號的層數
當層數是 0
時,才能處裡 +, -, *, /, %
✅ 完整代碼
評分結果(參考) : AC (2ms, 332KB)
#include <bits/stdc++.h>
using namespace std;
#define int long long
string s;
int s2i(int begin_, int end_){
int num = 0;
for (int i=begin_; i<end_; i++) {
num = num*10 + (s[i]-'0');
}
return num;
}
int calculate(int begin_, int end_) {
if (begin_ >= end_) return 0;
// handle + -
int layer = 0;
for(int i=end_-1; i>=begin_; i--) {
if(s[i] == ')') layer++;
else if(s[i] == '(') layer--;
else if((s[i] == '+' || s[i] == '-') && layer == 0) {
if(s[i] == '+') return calculate(begin_, i-1) + calculate(i+2, end_);
else return calculate(begin_, i-1) - calculate(i+2, end_);
}
}
// handle * / %
layer = 0;
for(int i = end_-1; i>=begin_; i--) {
if(s[i] == ')') layer++;
else if(s[i] == '(') layer--;
else if(layer == 0) {
if(s[i] == '*') return calculate(begin_, i-1) * calculate(i+2, end_);
if(s[i] == '/') return calculate(begin_, i-1) / calculate(i+2, end_);
if(s[i] == '%') return calculate(begin_, i-1) % calculate(i+2, end_);
}
}
// handle ( )
if(s[begin_] == '(' && s[end_-1] == ')') {
return calculate(begin_+2, end_-2);
}
return s2i(begin_, end_);
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
while(getline(cin, s)) {
cout << calculate(0, s.size()) << endl;
}
}