我参考了不少已有的解析,所以说我写的代码还是老掉牙的递归,对于CPP模拟计算式而言,这确实是最好的办法了

思路各位大神的题解已经说的很清楚了,我在这里主要是对于“开头负数是否可以处理”发表我的看法——可以不单独显示处理!

我们之所以可以处理负数,主要归功于(l > r)时返回0,这一个看似无聊的常规操作却能够奇妙的处理符号问题。我的代码同级是以右边的为优先,比如例子3+-5,先拿到-,之后分割为3+与5,5不用管,对于左边的3+,+右边pos+1会大于原本的r以至于返回0,也就是3+0-5,可以正常操作

我发现很多人的代码里,pos初始化都是-1,实际上可以改为LLONG_MIN

我们有举一个例子:-5 + 3,先拿到3,分为3与-5,我们看-5,右边拿到5,左边的符号右边会变为pos-1也就是-1,如果pos初始化为-1那确实是无计可施,不过变为LLONG_MIN,对于(0,-1),r会小于l,所以说会返回0,也就是0-5+3!

当然这也只是我的思路,如果有错也希望各位大佬指出

#include<bits/stdc++.h>
#define int long long
using namespace std;

string str;

int num(int l,int r)
{
    int ans = 0;
    
    for(int u = l;u <= r;u++)
    {
        ans = ans * 10 + (str[u] - '0');
    }
    
    return ans;
}
//经典转化,这里不使用string的原因只是因为我们实际上没有切割字符串,切割的实际上只有区间

int opp(char s)
{
    if(s == '+' || s == '-')
    {
        return 1;
    }
    else if(s == '*' || s == '/')
    {
        return 2;
    }
    else if(s == '^')
    {
        return 3;
    }
    else
    {
        return 0;
    }
}

int solve(int l,int r)
{
    if(l > r)
    {
        return 0;
    }
    
    int pos1 = LLONG_MIN,pos2 = LLONG_MIN,pos3 = LLONG_MIN;
    
    int cnt = 0;
    
    for(int o = l;o <= r;o++)
    {
        if(str[o] == '(')
        {
            cnt++;
        }
        else if(str[o] == ')')
        {
            cnt--;
        }
        
        if(cnt == 0)//要么是左右全对应上了,要么是压根没有。如果到了最后还不为0,我们有讨论方式
        {
            if(opp(str[o]) == 1)
            {
                pos1 = o;
            }
            else if(opp(str[o]) == 2)
            {
                pos2 = o;
            }
            else if(opp(str[o]) == 3)
            {
                pos3 = o;
            }
        }
    }
    
    if(pos1 == LLONG_MIN && pos2 == LLONG_MIN && pos3 == LLONG_MIN)
    {
        //除开只有括号的情况,还有可能是全程记录时cnt都没有正确对应上过
        //我们需要在这一步进行分类讨论
        
        if(cnt > 0 && str[l] == '(')
        {
            return solve(l + 1,r);
        }
        else if(cnt < 0 && str[r] == ')')
        {
            return solve(l,r - 1);
        }
        else if(cnt == 0 && str[r] == ')' && str[l] == '(')
        {
            return solve(l + 1,r - 1);
            //理想情况下(没有多余符号)的溢出条件
        }
        else
        {
            return num(l,r);
        }
        
        //核心是由于括号的优先级最高,所以说括号内的我们先不要去分割,不去记录他的pos,等到只有他时再去处理
        
    }
    else
    {
        if(pos1 > LLONG_MIN)
        {
            if(str[pos1] == '+')
            {
                return solve(l,pos1 - 1) + solve(pos1 + 1,r);
            }
            else
            {
                return solve(l,pos1 - 1) - solve(pos1 + 1,r);
            }
        }
        else if(pos2 > LLONG_MIN)
        {
            if(str[pos2] == '*')
            {
                return solve(l,pos2 - 1) * solve(pos2 + 1,r);
            }
            else
            {
                return solve(l,pos2 - 1) / solve(pos2 + 1,r);
            }            
        }
        else
        {
            return pow(solve(l,pos3 - 1),solve(pos3 + 1,r));
        }
    }
}

signed main() 
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    
    cin>>str;
    
    cout<<solve(0,str.length() - 1)<<endl;
    
    return 0;
}