表达式求值

HJ54 表达式求值

题目:

给定一个字符串描述的算术表达式,计算出结果值。

示例

输入:
400+5
输出:
405

解题方法:递归调用

这里细节比较多:
1、数据为负数
2、数据为超过9的数,如12,需要正确转换
3、遇到多重括号的时候,递归处理

代码
#include <cctype>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
    //几个细节:1、负号和减号全部转成加号+负数来计算
    //2、多对括号,采用迭代的方法求解子问题
int compute(string s, int left, int right){
//括号计算的初始变量
    char op = '+';
    int num = 0;
    vector<int> numVec;
    
    for(int i = left; i <= right; i++){
        if(isdigit(s[i])){
            num = num * 10 + s[i] - '0';
        }

        if(s[i] == '('){
            int layer = 0;
            int j = i;
            while(j <= right){
            if(s[j] == '('){
                layer++;
            }else if(s[j] == ')'){
                layer--;
                if(layer == 0)
                    break;
            }
            j++;
            }

            num = compute(s, i + 1, j - 1);
            i = j + 1;
        }

        if(!isdigit(s[i]) || i == right){
            switch (op) {//这里op是上一个符号
            case '+': numVec.push_back(num); break;
            case '-': numVec.push_back(-num);break;
            case '*': numVec.back() *= num;break;
            case '/': numVec.back() /= num;break;
            }
            op = s[i];//将当前符号赋值给op,作为下一次的运算符号
            num = 0;//每次遇到符号,就重置num的值
        }
    }
    int res = 0;
    for(auto i : numVec){
        res += i;
    }
    return res;

}

int main() {

    string s;
    cin >> s;

    cout << compute(s, 0, s.size() - 1) << endl;

}
// 64 位输出请用 printf("%lld")
总结

1、numVec存储正负数,解决了多重减号变正号的问题。因为之前自己用双栈来实现的时候,符号栈中连续的负号的处理会出现负负得正的问题。方法有问题,所以重新按照newcode官方给的思路写。
2、op和num的前置值很重要,在遇到负数时就比较好处理。在计算数据时,op存的是上一个符号。数据计算完成后,再把当前的符号赋值给op,用于下一次符号计算,这样保证了双目运算符取到两个操作数后才开始计算。
写的有些绕,下次再看到这题的时候,需要调试代码估计才能看懂。
3、需要注意迭代的条件和迭代后,i,j的更新

posted @ 2023-06-01 17:37  水水滴答  阅读(32)  评论(0编辑  收藏  举报