力扣练习---基本计算器(224)

题目描述:

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

实现一个基本的计算器来计算一个简单的字符串表达式的值。字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格  。

示例 1:  输入: "1 + 1"         输出: 2

示例 2:  输入: " 2-1 + 2 "    输出: 3

示例 3:  输入: "(1+(4+5+2)-3)+(6+8)"   输出: 23

说明:1、你可以假设所给定的表达式都是有效的。2、请不要使用内置的库函数 eval。

题目分析:

1、由于表达式中存在括号,并且内部括号内的子表达式计算优先级大于外部,因此数据结构考虑用栈;

2、加减法运算中(A+B)+C等价于A+(B+C),但是(A-B)+C不等价于A-(B+C),因此要保证子表达式的计算顺序为从左到右;

3、数据结构选用栈,子表达式计算顺序为从左到右,因此需要的入栈顺序为从右到左,也就是需要将输入逆序;

4、不要局限于题目示例,输入的每个数字不一定是1、2这样的简单数字,还可能为123等

解题思路:

1、逆序遍历输入,数字、运算符、右括号均入栈;

2、数字的位数不一定只有一位,可能存在多位;遍历数字时,由于逆序遍历,因此得到的位数顺序为个位、十位、百位...,这样就好处理了很多;

3、遍历过程中遇到左括号,需要将栈中的元素出栈并按照运算符计算,直到栈中元素为右括号为止,然后将计算结果入栈,然后继续遍历;

4、完成1/2/3后,如果栈不为空,继续出栈并计算;

Java代码:

public class LeetCode224_calculate {

    private static final char LEFT = '(';

    private static final char RIGTH = ')';

    private static final char ADD = '+';

    private static final char SUB = '-';

    private static final char SPACE = ' ';

    private static final int NUM_10 = 10;

    public int calculate(String s) {
        Stack<Object> stack = new Stack<>(); // 为了同时存储运算符和数字, 类型选择Object
        int number = 0;
        int digitCount = 0;
        // 逆序遍历
        for (int index = s.length() - 1; index >= 0; index--) {
            char ch = s.charAt(index);
            if (ch == SPACE) {
                continue;
            }

            if (Character.isDigit(ch)) {
                // 处理多位数字的场景
                number += Math.pow(NUM_10, digitCount) * (ch - '0');
                digitCount++;
            } else {
                if (digitCount > 0) {
                    stack.push(number);
                    number = 0;
                    digitCount = 0;
                }

                if (ch == LEFT) {
                    // 计算子表达式的取值
                    int subResult = calcSub(stack);
                    stack.pop(); // 弹出右括号
                    stack.push(subResult);
                } else {
                    stack.push(ch);
                }
            }
        }

        // 这一步很重要, 处理最后一个单纯数字场景
        if (digitCount > 0) {
            stack.push(number);
        }

        return calcSub(stack);
    }

    private int calcSub(Stack<Object> stack) {
        int result = 0;
        if (!stack.isEmpty()) {
            // 开始处理时栈不为空, 那么栈顶一定是数字
            result = (int)stack.pop();
        }

        while (!stack.isEmpty() && !((char)stack.peek() == RIGTH)) {
            char operate = (char)stack.pop();
            if (operate == ADD) {
                result += (int)stack.pop();
            } else if (operate == SUB) {
                result -= (int)stack.pop();
            }
        }
        return result;
    }
}

力扣运行结果:

猜你喜欢

转载自www.cnblogs.com/sniffs/p/12451821.html