Leetcode 227 basic caculator

Implement a basic calculator to evaluate a simple expression string.java

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

You may assume that the given expression is always valid.lua

Some examples:
spa

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


分析:題目主要的難點在於*,/比+,-有更高的優先級,因此,當處理到低優先級的+,-時,不能直接計算,而要等看後面的操做符,能夠分爲兩種狀況:code

  1. 若是後續的操做符是相同優先級,則要先計算前面操做符;orm

  2. 若是後續的是高優先級的操做符,則要先計算後續的操做符;string


處理好這兩種狀況,就能夠完成了;it

public class Solution {

    public static void main(String[] args) {
        System.out.println("3+2*2 = " + calculate("3+2*2"));
        System.out.println(" 3/2  = " + calculate(" 3/2 "));
        System.out.println(" 3+5 / 2  = " + calculate(" 3+5 / 2 "));
    }

    public static int calculate(String s) {
        char[] cs = s.toCharArray();

        Stack stack = new Stack();
        for (int i = 0; i < cs.length; ) {
            if (cs[i] == ' ') {
                i++;
                continue;
            }

            if (isMul(cs[i]) || isAdd(cs[i])) {
                stack.addOp(cs[i]);
                i++;
                continue;
            }
            int num = 0;
            while (i < cs.length && isNum(cs[i])) {
                num = num * 10 + (cs[i] - '0');
                i++;
            }
            stack.addNum(num);
        }

        return stack.eval();
    }

    static boolean isNum(char c) {
        return c >= '0' && c <= '9';
    }

    static boolean isMul(char c) {
        return c == '*' || c == '/';
    }

    static boolean isAdd(char c) {
        return c == '+' || c == '-';
    }

    static class Stack {
        int[] nums = new int[3];
        int pnum = -1;
        char[] ops = new char[2];
        int pop = -1;

        public void addOp(char op) {
            if (isAdd(op) && pop == 0) {
                int b = nums[pnum--];
                int a = nums[pnum--];
                int c = calc(a, b, ops[pop--]);
                nums[++pnum] = c;
            }
            ops[++pop] = op;
        }

        public void addNum(int num) {
            nums[++pnum] = num;
            if (pop >= 0 && isMul(ops[pop])) {
                int b = nums[pnum--];
                int a = nums[pnum--];
                int c = calc(a, b, ops[pop--]);
                nums[++pnum] = c;
            }
        }

        int calc(int a, int b, char op) {
            int c = 0;
            switch (op) {
                case '+':
                    c = a + b;
                    break;
                case '-':
                    c = a - b;
                    break;
                case '*':
                    c = a * b;
                    break;
                case '/':
                    c = a / b;
                    break;
                default:
                    throw new IllegalArgumentException("unknown operator " + c);
            }
            return c;
        }

        public int eval() {
            if (pnum == 0) {
                return nums[pnum--];
            } else {
                int b = nums[pnum--];
                int a = nums[pnum--];
                char c = ops[pop--];
                return calc(a, b, c);
            }
        }
    }
}

這裏模擬了一個Stack,io

  1. 以處理1 + 2 * 3爲例,在加入2的時候,不能計算1 + 2, 由於不知道後續操做符的優先級;等加入*的時候,能夠肯定當前的優先級確定比前面的大,(在stack裏面至多存在一個*或者/);當加入3的時候,發現前面是一個高優先級的*,能夠直接計算,獲得6,並把結果放到棧頂。繼續處理後續的輸入;class

  2. 以處理1 + 2 - 3爲例,在輸入-號以前,和前面的處理是同樣的;判斷是低優先級的,而且棧底有輸入,將棧底的先計算出來,獲得3,從新壓入棧底(不要忘記了),而後加入新的-;而後加入3;


因此,能夠看到,棧裏面最多隻有4個元素,2個操做數,和2個操做符;

時間複雜度是O(n), 空間複雜度是O(1);

相關文章
相關標籤/搜索