栈、队列、堆--06-基本计算器[困难]

https://leetcode-cn.com/problems/basic-calculator/

题干

实现一个基本的计算器来计算一个简单的字符串表达式 s 的值。

示例 1:

  • 输入:s = "1 + 1"
  • 输出:2

示例 2:

  • 输入:s = " 2-1 + 2 "
  • 输出:3

示例 3:

  • 输入:s = "(1+(4+5+2)-3)+(6+8)"
  • 输出:23

思路

使用两个栈来完成计算,其中一个栈放数字num,一个放操作op( ‘+’、‘-’、‘(’、‘)’ )。

  • 当检测到空格时,跳过。
  • 当检测到“ +、-、( ”时,不能开始计算。
  • 当检测到数字时,插入,当op栈首不为'(',且有+或-的操作时,计算一次。
  • 当遇到' ) '时,说明括号内已经计算完成,弹出左括号。

例如-1+2+(14+(5-6))

 

class Solution {
public:
    int calculate(string s) {
        stack<char> op; //存放+-()
        stack<int> num; //存放数字
        long temp_num = 0;
        //循环整个string
        for (int i = 0; i < s.length(); i++) {
            if (s[i] == ' ') continue; //处理空格

            //遇到+-(符号时,暂不计算,放入op栈中
            if (s[i] == '+' || s[i] == '-' || s[i] == '(') 
                op.push(s[i]);

            //当遇到)时,说明一个括号的内容载入完成,可以计算
            else if (s[i] == ')') {
                op.pop(); //去掉op中的左括号
                if (!op.empty() && op.top() != '(')
                    calc(op, num);
            }

            //剩下的只有数字
            else {
                //生成数字
                while (i < s.length() && isdigit(s[i])) {
                    //isdigit判定当前char是否属于0~9
                    temp_num = temp_num * 10 + s[i] - '0';
                    i = i + 1;
                }
                i = i - 1; //因为向后多扫描了一位,当不是数字时需要还原
                num.push(temp_num);
                temp_num = 0; //清0,以便下次使用
                if (!op.empty() && op.top() != '(')
                    calc(op,num);
            }
        }
        
        return num.top();
    }

    //计算两个数的加或减,并放入栈
    void calc(stack<char>& op, stack<int>& num)
    {
        if (num.size() == 1) {  //处理算式最开始带负号的情况
            int x = num.top();
            num.pop();
            num.push(-x);
            op.pop();
            return;
        }
        int a = num.top();
        num.pop();
        int b = num.top();
        num.pop();
        if (op.top() == '+')
            num.push(b + a);
        else if (op.top() == '-')
            num.push(b - a);
        op.pop();//去掉操作的符号
    }
};
#include<iostream>
#include<fstream>
#include<string>
#include<stack>
#include<vector>
using namespace std;

class Solution {
public:
    int calculate(string s) {
        stack<char> op; //存放+-()
        stack<int> num; //存放数字
        long temp_num = 0;
        //循环整个string
        for (int i = 0; i < s.length(); i++) {
            if (s[i] == ' ') continue; //处理空格

            //遇到+-(符号时,暂不计算,放入op栈中
            if (s[i] == '+' || s[i] == '-' || s[i] == '(') 
                op.push(s[i]);

            //当遇到)时,说明一个括号的内容载入完成,可以计算
            else if (s[i] == ')') {
                op.pop(); //去掉op中的左括号
                if (!op.empty() && op.top() != '(')
                    calc(op, num);
            }

            //剩下的只有数字
            else {
                //生成数字
                while (i < s.length() && isdigit(s[i])) {
                    //isdigit判定当前char是否属于0~9
                    temp_num = temp_num * 10 + s[i] - '0';
                    i = i + 1;
                }
                i = i - 1; //因为向后多扫描了一位,当不是数字时需要还原
                num.push(temp_num);
                temp_num = 0; //清0,以便下次使用
                if (!op.empty() && op.top() != '(')
                    calc(op,num);
            }
        }
        
        return num.top();
    }

    //计算两个数的加或减,并放入栈
    void calc(stack<char>& op, stack<int>& num)
    {
        if (num.size() == 1) {  //处理算式最开始带负号的情况
            int x = num.top();
            num.pop();
            num.push(-x);
            op.pop();
            return;
        }
        int a = num.top();
        num.pop();
        int b = num.top();
        num.pop();
        if (op.top() == '+')
            num.push(b + a);
        else if (op.top() == '-')
            num.push(b - a);
        op.pop();//去掉操作的符号
    }
};

void test01() {
	
	string str1 = "1+121-( 14+(5-6))";
    string str2 = "2147483647";
    string str3 = "-1+2+(14-(5-6))";
	Solution s;
	int result = s.calculate(str3);
	cout << result << endl;
}

int main() {
	test01();

	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值