比较头痛的点是存在括号 那么该如何消去括号呢 注意到括号使用是合法的 那么括号一定成对出现
那么我只需要每次遍历 记录左右括号的出现 左括号记为1,右括号记为-1 当我cnt == 0时 此时肯定不在括号内 这个时候出现的加减乘除乘方就是运算优先级最低的(当然这里面也是要区分运算优先级的 肯定时加减 再乘除 最后乘方)
但是还存在一种情况 整个表达式都被括号框住 这体现在没有记录到运算优先级最低的符号(位置) 那么此时我就要消去外层括号 即return cal(l + 1, r - 1)
剩下就很好操作了 先加减 再乘除 最后乘方 即可轻松解决
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
string s;
ll stoint(int l, int r) {
ll sum = 0;
for (int i = l;i <= r; ++ i) {
sum = sum * 10 + s[i] - '0';
}
return sum;
}
ll cal(int l, int r) {
int cnt = 0;
int pos1 = -1, pos2 = -1, pos3 = -1;
for (int i = l;i <= r; ++ i) {
if (s[i] == '(') cnt ++;
if (s[i] == ')') cnt --;
if (cnt == 0) {
if (s[i] == '+' || s[i] == '-') pos1 = i;
else if (s[i] == '*' || s[i] == '/') pos2 = i;
else if (s[i] == '^') pos3 = i;
}
}
if (pos1 == -1 && pos2 == -1 && pos3 == -1) {
if (cnt == 0 && s[l] == '(') return cal(l + 1, r - 1);
/*
if (cnt < 0 && s[r] == ')') return cal(l, r - 1);
if (cnt > 0 && s[l] == '(') return cal(l + 1, r);
如果括号不匹配就需要这两行来进行判断
*/
return stoint(l, r);
}
if (pos1 != -1) {
if (s[pos1] == '+') return cal(l, pos1 - 1) + cal(pos1 + 1, r);
else return cal(l, pos1 - 1) - cal(pos1 + 1, r);
}
else if (pos2 != -1) {
if (s[pos2] == '*') return cal(l, pos2 - 1) * cal(pos2 + 1, r);
else return cal(l, pos2 - 1) / cal(pos2 + 1, r);
}
else if (pos3 != -1) {
return pow(cal(l, pos3 - 1), cal(pos3 + 1, r));
}
return 0;
}
int main () {
ios::sync_with_stdio(0), cin.tie(0);
cin >> s;
cout << cal(0, s.size() - 1) << '\n';
}