[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();
    }
}