【Leetcode】227.基本计算器 Ⅱ

## 题目:
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
- `1 <= s.length <= 3 * 105`
-   `s` 由整数和算符 `('+', '-', '*', '/')` 组成,中间由一些空格隔开

整数除法仅保留整数部分。

你可以假设给定的表达式总是有效的。所有中间结果将在 [-231, 231 - 1] 的范围内。

注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。

### 示例:
#### 示例 1:
输入:s = "3+2*2"
输出:7

#### 示例2:
输入:s = " 3/2 "
输出:1

#### 示例3:
输入:s = " 3+5 / 2 "
输出:5

---
【方法一】双栈
![[Pasted image 20220901183359.png]]
```
class Solution {

    //思路:用两个栈,一个数字栈,一个符号栈;以及一个哈希表来存储运算符号的优先级

    static Stack<Integer> num = new Stack<Integer>();

    static Stack<Character> op = new Stack<Character>();

    static HashMap<Character, Integer> map = new HashMap<Character, Integer>();

  

    //定义一个eval()函数:用于从数字栈num中弹出两个数字a和b,再从操作符栈op中弹出操作符号,进行计算后将结果数字加入到数字栈num中。

    static void eval(){

        int a = num.pop();

        int b = num.pop();

        int c = op.pop();

        int res = 0; //a和b经c运算后结果

  

        if(c == '+') res = a + b;

        else if(c == '-') res = b - a;

        else if(c == '*') res = a * b;

        else res = b / a;

        num.push(res); //将结果入栈num

    }

  

    public int calculate(String s) {

        s = '0' + s; //对给的字符串表达式开头是负数的处理

        map.put('+', 1); //设计一个哈希表来存储'+','-','*','/' 优先级,我们将'+'和'-'设为1级优先级,将'*'和'/'设为2级优先级。
        map.put('-', 1);
        map.put('*', 2);
        map.put('/', 2);

  

        for(int i = 0; i < s.length(); i++){
            char c = s.charAt(i);
            if(c == ' ') continue; //跳过空格
            if(c >= '0' && c <= '9'){ //当c是数字,读取一个连续的数字
                int x = 0
                 while(i < s.length() && s.charAt(i) >= '0' && s.charAt(i) <= '9'){
                    x = x * 10 + s.charAt(i++) - '0';
                }
                i--;
                num.push(x);
            }else{ //当c是操作符

                //当op栈非空且栈顶操作符优先级大于等于当前操作符c的优先级,进行eval()操作
                while(!op.isEmpty() && map.get(op.peek()) >= map.get(c)){
                    eval();
                }
                op.push(c);
            }
        }
        while(!op.isEmpty()) eval();
  

        return num.pop();

    }
}
```

【方法二】单栈
说明:**所有运算最后都是一个个数做加法。**
    遇到减号,就让这个数变负
    遇到乘号,就让当前的数乘上之前的数
    遇到除号,就让当前数被之前的数除
所以需要一个栈,去存这些最后会做加法的计算结果;还要一个变量,记录上一个运算符是什么,它决定了怎么处理当前的数
```
class Solution {
    public int calculate(String s) {
        //Deque<Integer> stack = new ArrayDeque<Integer>(); //用Deque比Stack耗时少
        
        Stack<Integer> stack = new Stack<Integer>();
        char preSign = '+'; //此变量记录上一个运算符是什么
        int num = 0;
        int n = s.length();
        
        for (int i = 0; i < n; ++i) {
            if (Character.isDigit(s.charAt(i))) {
                num = num * 10 + s.charAt(i) - '0';
            }
            if (!Character.isDigit(s.charAt(i)) && s.charAt(i) != ' ' || i == n - 1) {
                switch (preSign) {
                case '+':
                    stack.push(num);
                    break;
                case '-':
                    stack.push(-num);
                    break;
                case '*':
                    stack.push(stack.pop() * num);
                    break;
                default:
                    stack.push(stack.pop() / num);
                }
                preSign = s.charAt(i);
                num = 0;
            }
        }
        
        int ans = 0;
        while (!stack.isEmpty()) {
            ans += stack.pop();
        }
        
        return ans;
    }
}
```


【方法三】逆波兰式???

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值