比较头痛的点是存在括号 那么该如何消去括号呢 注意到括号使用是合法的 那么括号一定成对出现 那么我只需要每次遍历 记录左右括号的出现 左括号记为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';
}