zoukankan      html  css  js  c++  java
  • 力扣练习001---基本计算器(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;
        }
    }

    力扣运行结果:

  • 相关阅读:
    表达式目录树(Expression)
    六大设计原则【单一职责】【里氏替换】【 迪米特法则】【依赖倒置原则】【接口隔离原则】【开闭原则】
    lambda,linq
    c#中的特性Attribute
    CentOS7部署Nginx
    NetCore项目的部署
    ABP+NetCore+Vue.js实现增删改查
    Abp数据库迁移注意事项
    MVC分页
    AspNet5 Changes to [Activate] in beta-5
  • 原文地址:https://www.cnblogs.com/sniffs/p/12451821.html
Copyright © 2011-2022 走看看