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
若是後續的操做符是相同優先級,則要先計算前面操做符;orm
若是後續的是高優先級的操做符,則要先計算後續的操做符;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 + 2 * 3爲例,在加入2的時候,不能計算1 + 2, 由於不知道後續操做符的優先級;等加入*的時候,能夠肯定當前的優先級確定比前面的大,(在stack裏面至多存在一個*或者/);當加入3的時候,發現前面是一個高優先級的*,能夠直接計算,獲得6,並把結果放到棧頂。繼續處理後續的輸入;class
以處理1 + 2 - 3爲例,在輸入-號以前,和前面的處理是同樣的;判斷是低優先級的,而且棧底有輸入,將棧底的先計算出來,獲得3,從新壓入棧底(不要忘記了),而後加入新的-;而後加入3;
因此,能夠看到,棧裏面最多隻有4個元素,2個操做數,和2個操做符;
時間複雜度是O(n), 空間複雜度是O(1);