• [LeetCode-JAVA] Basic Calculator II


    题目:

    Implement a basic calculator to evaluate a simple expression string.

    The expression string contains only non-negative integers, +-*/ operators and empty spaces . The integer division should truncate toward zero.

    You may assume that the given expression is always valid.

    Some examples:

    "3+2*2" = 7
    " 3/2 " = 1
    " 3+5 / 2 " = 5
    

    Note: Do not use the eval built-in library function.

    题意:简易计算器,可以进行四则运算

    思路:在I的基础上可以很清晰的分析此题,利用两个Stack,一个存储数字,一个存储符号需要注意一下几点:

     (1)连续的数字需要进行处理;

     (2)乘除需要在后一个数字入栈后处理;

     (3)最后栈内剩余为加减法,只需要一步步弹出即可,需要记住一次只弹出一个数字和符号,不能两个数字运算,在I中有说明,遗忘的话可以点击->  Basic Calculator I

     (4)需要对最后一个数字进行特殊处理,因为前面的方法只有检测到有符号的时候才会将数字如栈。

    代码(后面有优化版):

    public class Solution {
        public int calculate(String s) {
            if(s == null || s.length() == 0)
                return 0;
            Stack<Integer> num = new Stack<Integer>();
            Stack<Character> symbol = new Stack<Character>();
            
            boolean isNum = false;
            int count = 0;
            for(int i = 0 ; i < s.length() ; i++){
                if(s.charAt(i) == ' ')
                    continue;
                char temp = s.charAt(i);
                if(Character.isDigit(temp)){
                    count = count * 10 + (temp - '0') ;
                    isNum = true;
                }else if(isNum){
                    num.push(count);
                    count = 0;
                    isNum = false;
                    if(!symbol.isEmpty() && (symbol.peek() == '*' || symbol.peek() == '/')){
                        char tempSymbol = symbol.pop();
                        int b = num.pop();
                        int a = num.pop();
                        if(tempSymbol == '*'){
                            num.push(a*b);
                        }else{
                            num.push(a/b);
                        }
                    }
                }
                if(!Character.isDigit(temp)){
                    symbol.push(temp);
                }
            }
            if(isNum){
                num.push(count);
                if(!symbol.isEmpty() && (symbol.peek() == '*' || symbol.peek() == '/')){
                    char tempSymbol = symbol.pop();
                    int b = num.pop();
                    int a = num.pop();
                    if(tempSymbol == '*'){
                        num.push(a*b);
                    }else{
                        num.push(a/b);
                    }
                }
            }
            
            if(!symbol.isEmpty()){
                int rep = 0;
                while(!symbol.isEmpty()){
                    char tempSymbol = symbol.pop();
                    int a = num.pop();
                    if(tempSymbol == '+'){
                        rep+=a;
                    }else{
                        rep-=a;
                    }
                }
                num.push(rep + num.pop());
            }
            
            return num.pop();
        }
    }

    优化思路:注意到代码有冗余的部分,是因为每一次数字入栈是在判断有符号的时候,这时,可以人为的在初始出入的String的末尾加入非运算符号,这样可以将二者整合到一起。

    优化后代码:

    public class Solution {
        public int calculate(String s) {
            if(s == null || s.length() == 0)
                return 0;
            Stack<Integer> num = new Stack<Integer>();
            Stack<Character> symbol = new Stack<Character>();
            s += "#";
            boolean isNum = false;
            int count = 0;
            for(int i = 0 ; i < s.length() ; i++){
                if(s.charAt(i) == ' ')
                    continue;
                char temp = s.charAt(i);
                if(Character.isDigit(temp)){
                    count = count * 10 + (temp - '0') ; // 连续的数字
                    isNum = true;
                }else{
                    if(isNum){  // 遇到符号 将前面数字压入
                        num.push(count);
                        count = 0;
                        isNum = false;
                        if(!symbol.isEmpty() && (symbol.peek() == '*' || symbol.peek() == '/')){
                            char tempSymbol = symbol.pop();
                            int b = num.pop();
                            int a = num.pop();
                            if(tempSymbol == '*'){
                                num.push(a*b);
                            }else{
                                num.push(a/b);
                            }
                        }
                    }
                    if(temp != '#'){ // 将符号压入
                        symbol.push(temp);
                    }
                }
            }
            
            if(!symbol.isEmpty()){
                int rep = 0;
                while(!symbol.isEmpty()){  // 加减运算
                    char tempSymbol = symbol.pop();
                    int a = num.pop();
                    if(tempSymbol == '+'){
                        rep+=a;
                    }else{
                        rep-=a;
                    }
                }
                num.push(rep + num.pop());
            }
            
            return num.pop();
        }
    }
  • 相关阅读:
    JSON.parse与eval
    加密算法
    asp.net权限管理
    asp.net登录状态验证
    U3D Debug.log的问题
    yield(C# 参考)
    U3D 动态创建Prefab的多个实例
    U3D事件系统总结
    C#事件与接口
    C#泛型委托,匿名方法,匿名类
  • 原文地址:https://www.cnblogs.com/TinyBobo/p/4608352.html
Copyright © 2020-2023  润新知