LEECODE【基础表达式】

题目

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。

例如1:输入 s=“1+1”
        输出:2
例如2: 输入 s = "(1+(4+5+2)-3)+(6+8)"

           输出:23

  • s 由数字、'+'、'-'、'('、')'、和 ' ' 组成
  • s 表示一个有效的表达式

思路

    先去除空格

    然后先找到右括号,再找到该有括号对应的左括号,在二者之间一定不再存在括号,计算该普通表达式的值

    再将计算得到的结果,放回原先括号表达式的位置,重复上一步的运算过程

代码

#include <string>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

class Solution {
public:
    int calculate(string s) {
        string str = remove_space(s);
        return cal_simple(str);
    }
    string itoa(int num) {
        char buffer[256];
        sprintf(buffer, "%d", num);
        return string(buffer);
    }
private:
    int cal_simple(string s) {
        // 找出第一个)
        size_t right_found = s.find(")");
        while(right_found!=string::npos) { // 找到右括号
            // 从该位置起反向找左括号
            size_t left_found = s.rfind("(", right_found);
            // 计算括号内表达式的值
            string new_str = s.substr(left_found+1, right_found-left_found-1);
            cout << "new expresion is " << new_str << endl;
            int new_result = cal_simple(new_str);
            cout << "new result is " << new_result << endl;
            string next_str; // 新的表达式
            // 将计算所得的结果放回原表达式中
            if(left_found==0) { // 左括号在第一个元素
                next_str = itoa(new_result) + s.substr(right_found+1); // TODO 会不会有越界问题 
            }else { // 左括号非第一个元素
                string left_str = s.substr(0, left_found-1);
                char left_oper = s.at(left_found-1);
                if(left_oper=='+' && new_result < 0) {
                    left_oper = '-';
                }else if(left_oper=='-' && new_result < 0) {
                    left_oper = '+';
                }
                left_str.push_back(left_oper);
                if(new_result<0) {
                    new_result *= -1;
                }
                next_str = left_str + itoa(new_result);
                if(right_found != s.length()-1) {
                    next_str += s.substr(right_found+1);
                }
            }
            s = next_str; // 替代原先的表达式
            cout << "now the expresion is " << next_str << endl;
            // 寻找下一个右括号
            right_found = s.find(")");
        }
        { // 未找到
            int left_num = 0; // 左操作数
            int right_num = 0; // 右操作数
            char oper = '+'; // 操作符
            char next_operator = '+'; // 下一个操作符
            int right_idx = 0; // 操作符所在的位置
            if(s.at(0)=='+' || s.at(0)=='-') { // 首部为符号
                oper = s.at(0);
                right_idx = 1;
            }
            // 寻找下一个符号的位置
            while(true) {
                size_t next_plus_idx = s.find("+", right_idx);
                size_t next_minus_idx = s.find("-", right_idx);
                if(next_plus_idx==string::npos && next_minus_idx==string::npos) { // 没有符号了
                    break;
                }
                size_t next_idx = 0;
                if(next_plus_idx!=string::npos && next_minus_idx!=string::npos) {
                    if(next_plus_idx<next_minus_idx) {
                        next_operator = '+';
                        next_idx = next_plus_idx;
                    }else {
                        next_operator = '-';
                        next_idx = next_minus_idx;
                    }
                }else if(next_plus_idx!=string::npos) {
                    next_operator = '+';
                    next_idx = next_plus_idx;
                }else {
                    next_operator = '-';
                    next_idx = next_minus_idx;
                }
                right_num = atoi(s.substr(right_idx, next_idx-right_idx).c_str());
                if(oper=='+') {
                    left_num += right_num;
                }else {
                    left_num -= right_num;
                }
                oper = next_operator;
                right_idx = next_idx+1;
            }
            // 收尾工作
            right_num = atoi(s.substr(right_idx).c_str());
            if(oper=='+') {
                return left_num + right_num;
            }else {
                return left_num - right_num;
            }
        }
        return 0;
    }
    // 去掉空格
    string remove_space(const string& str) {
        string ret;
        for(int i=0; i!=str.length(); i++) {
            if(str.at(i)!=' ') {
                ret.push_back(str.at(i));
            }
        }
        return ret;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值