【算法】【线性表】【字符串】基本计算器 II

1  题目

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

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

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

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

示例 1:

输入:s = "3+2*2"
输出:7

示例 2:

输入:s = " 3/2 "
输出:1

示例 3:

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

提示:

  • 1 <= s.length <= 3 * 105
  • s 由整数和算符 ('+', '-', '*', '/') 组成,中间由一些空格隔开
  • s 表示一个 有效表达式
  • 表达式中的所有整数都是非负整数,且在范围 [0, 231 - 1] 内
  • 题目数据保证答案是一个 32-bit 整数

2  解答

这道题着实对我有点难度,我以前知道表达式的计算,是用栈的压栈弹栈实现的,我记得是后缀表达式如果是数字直接压栈,如果碰到运算符就弹出两个数然后进行运算,然后将运算的结果再压栈,莫非这个要将表达式变成后缀表达式么?哈哈哈。题中的表达式是个中序表达式,这个该怎么利用栈计算呢?这个是用的数字前缀来做的,你比如 3 + 2 * 2 就是 +3 + 2 * 2 每个数都是根据它前边的前缀来判断是做什么操作的,如果是加减就压栈,如果是乘除就把栈顶的数和当前的数运算然后压进去,代码如下:

class Solution {
    public int calculate(String s) {
        // 当前获取到的数字
        int currentNum = 0;
        // 当前数的前缀操作默认+
        char preSign = '+';
        // 核心思想就是通过一个栈来进行计算,乘除运算 加减放进栈中,最后将栈中的元素都加起来就是表达式的结果
        Deque<Integer> stack = new ArrayDeque<>();
        int len = s.length();
        for (int i = 0; i < len; i++) {
            char c = s.charAt(i);
            // 空格直接略过
            if (c == ' ') continue;
            // 如果是数字的话,先读取一个数
            if (Character.isDigit(c)) {
                // 这个我还是看的题解= = 因为它表达式不仅仅是个数 他还有 10 + 300 + 345 这种多位的数  所以每次都是 乘10 加上个位数
                currentNum = currentNum * 10 + c - '0';
                continue;
            }
            // 到这里 currentNum 就是一个完整的数字了 并且是个操作符了
            operate(stack, preSign, currentNum);
            preSign = c;
            currentNum = 0;
        }
        // 最后一位没参与运算呢还
        operate(stack, preSign, currentNum);

        // 求和
        int res = 0;
        while (!stack.isEmpty()) {
            res += stack.pop();
        }
        return res;    
    }

    private void operate(Deque<Integer> stack, char preSign, int currentNum) {
        switch (preSign) {
            // 如果是加减的话 则直接把 currentNum 放进去
            case '+': {
                stack.push(currentNum);
            } break;
            case '-': {
                stack.push(-currentNum);
            } break;
            // 这里说明是乘除了 那就从把栈顶的取出来和 currentNum 进行运算,然后将运算结果放里边
            case '*': {
                stack.push(stack.pop() * currentNum);
            } break;
            case '/': {
                stack.push(stack.pop() / currentNum);
            } break;
            default: {}
        }
    }
}

加油。

posted @ 2024-03-26 08:32  酷酷-  阅读(11)  评论(0编辑  收藏  举报