jadvpetc

导航

计算器相关题目总结

选自leetcode basic calculator

 

Version 1: Support [ + - ]

 

(not tested)

 

class Solution {
    
    public int calculate(String s) {
        int len = s.length(), sign = 1, res = 0, num = 0;
        for (int i = 0; i < len; i++) {
            char c = s.charAt(i);
            if (c == ' ') continue;
            if (Character.isDigit(c)) {
                num = num * 10 + c - '0';
                if (i == len - 1 || !Character.isDigit(s.charAt(i + 1))) { // 当后一位不是数字时就停止并且reset
                    res += sign * num;
                    num = 0;
                }
            } else { // + or -
                if (c == '+') sign = 1; // 记录之前的状态,因为数字是一个位一个位
                if (c == '-') sign = -1;
            }
        }
        return res;
    }
    
}

Version 2: Support [ + - ( ) ] (this problem)

class Solution {
    
    public int calculate(String s) {
        int len = s.length(), sign = 1, res = 0, num = 0;
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < len; i++) {
            char c = s.charAt(i);
            if (c == ' ') continue; //只要数字不会被拆开,用这个就没问题。
            if (Character.isDigit(c)) {
                num = num * 10 + c - '0';
                if (i == len - 1 || !Character.isDigit(s.charAt(i + 1))) {
                    res += sign * num;
                    num = 0;
                }
            } else { // + - ( )
                if (c == '+') {
                    sign = 1;
                }
                if (c == '-') {
                    sign = -1;
                }
                if (c == '(') {
                    stack.push(res);
                    stack.push(sign);
                    res = 0;
                    sign = 1;
                }
                if (c == ')') {
                    res = res * stack.pop() + stack.pop(); //现在的和sign+之前的
                }               
            }
        }
        return res;
    }
    
}

Version 3: Support [ + - * / ]

class Solution {
    public int calculate(String s) {
        if (s == null || s.length() == 0) return 0;
        int len = s.length();
        int num = 0;
        char sign = '+';
        int curr = 0, res = 0; //important, use curr to store value of last segment.
        for (int i = 0; i < len; i++) {
            if (s.charAt(i) == ' ') continue;
            if (!Character.isDigit(s.charAt(i))) {
                num = 0;
                sign = s.charAt(i);
                if (sign == '+' || sign == '-') {
                    res += curr;
                    curr = 0; // not necessary
                }
            } else {
                num = num * 10 + s.charAt(i) - '0';
                if (i == len - 1 || !Character.isDigit(s.charAt(i + 1))) {
                    if (sign == '+') curr = num;
                    if (sign == '-') curr = -num;
                    if (sign == '*') curr *= num;
                    if (sign == '/') curr /= num;
                }
            }         
        }
        res += curr; // add last segment
        return res;
    }
}

Version 4: Support [ + - * / ( ) ]

 

Should be easily derived from Version 6, just remove anything related to ^.

 

Version 5: Support [ + - * / ^ ]

class Solution {
    
    public int calculate(String s) {
        // remove spaces //这部分也可以放在下面判断,一句搞定,是空格的时候跳过
        String[] strs = s.split(" ");
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < strs.length; i++) {
            sb.append(strs[i]);
        }
        s = sb.toString();
        
        // init
        if (s == null || sb.length() == 0) return 0;
        int num = 0;
        Stack<Integer> numStack = new Stack<>();
        Stack<Character> opStack = new Stack<>();
        Map<Character, Integer> map = new HashMap<>();
        map.put('+', 1); map.put('-', 1);
        map.put('*', 2); map.put('/', 2);
        map.put('^', 3);
        
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (Character.isDigit(c)) {
                num = num * 10 + c - '0';
                if (i == s.length() - 1 || !Character.isDigit(s.charAt(i + 1))) {
                    numStack.push(num);
                    num = 0;                  
                }
            } else { // op: + - * / ^
                if (opStack.empty() || map.get(c) > map.get(opStack.peek())) {
                    opStack.push(c);
                } else {
                    while (!opStack.empty() && map.get(c) <= map.get(opStack.peek())) {
                        helper(numStack, opStack);
                    }
                    opStack.push(c);
                }                     
            }           
        }
        
        while (!opStack.empty()) {
            helper(numStack, opStack);
        }
        return numStack.pop();
    }
    
    private void helper(Stack<Integer> numStack, Stack<Character> opStack) {
        int b = numStack.pop();
        int a = numStack.pop();
        char op = opStack.pop();
        if (op == '+') numStack.push(a + b);
        if (op == '-') numStack.push(a - b);
        if (op == '*') numStack.push(a * b);
        if (op == '/') numStack.push(a / b);
        if (op == '^') numStack.push((int)Math.pow(a, b));
    }

}

Version 6: Support [ + - * / ^ ( ) ]

class Solution {
    
    public int calculate(String s) {
        // remove spaces //这部分也可以放在下面判断,一句搞定,是空格的时候跳过
        String[] strs = s.split(" ");
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < strs.length; i++) {
            sb.append(strs[i]);
        }
        s = sb.toString();
        
        // init
        if (s == null || sb.length() == 0) return 0;
        int num = 0;
        Stack<Integer> numStack = new Stack<>();
        Stack<Character> opStack = new Stack<>();
        Map<Character, Integer> map = new HashMap<>();
        map.put('+', 1); map.put('-', 1);
        map.put('*', 2); map.put('/', 2);
        map.put('^', 3);
        
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (Character.isDigit(c)) {
                num = num * 10 + c - '0';
                if (i == s.length() - 1 || !Character.isDigit(s.charAt(i + 1))) {
                    numStack.push(num);
                    num = 0;                  
                }
            } else { // op or ()
                if (c == '(') {
                    opStack.push(c);
                }
                if (c == ')') {
                    while (!opStack.empty() && opStack.peek() != '(') {
                        helper(numStack, opStack);
                    }
                    opStack.pop(); // pop the '('
                }
                if (map.containsKey(c)) { // + - * / ^
                    if (opStack.empty() || opStack.peek() == '(' || map.get(c) > map.get(opStack.peek())) {
                        opStack.push(c);
                    } else {
                        while (!opStack.empty() && opStack.peek() != '(' && map.get(c) <= map.get(opStack.peek())) {
                            helper(numStack, opStack);
                        }
                        opStack.push(c);
                    }                 
                }              
            }           
        }
        
        while (!opStack.empty()) {
            helper(numStack, opStack);
        }
        return numStack.pop();
    }
    
    private void helper(Stack<Integer> numStack, Stack<Character> opStack) {
        int b = numStack.pop();
        int a = numStack.pop();
        char op = opStack.pop();
        if (op == '+') numStack.push(a + b);
        if (op == '-') numStack.push(a - b);
        if (op == '*') numStack.push(a * b);
        if (op == '/') numStack.push(a / b);
        if (op == '^') numStack.push((int)Math.pow(a, b));
    }

}

posted on 2020-01-10 20:29  jadvpetc  阅读(449)  评论(0编辑  收藏  举报