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);