Leetcode[224, 227] Basic Calculator

###Task1 Implement a basic calculator to evaluate a simple expression string.

The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces .

You may assume that the given expression is always valid.

Some examples:

"1 + 1" = 2
" 2-1 + 2 " = 3
"(1+(4+5+2)-3)+(6+8)" = 23 Note: Do not use the eval built-in library function.

###Python

class Solution(object):
    def calculate(self, s):
        """
        :type s: str
        :rtype: int
        """
        self.calculator = ['+', '-', '*', '/']
        tokens = self.convertRPN(s)
        return self.compute(tokens)
    
    def convertRPN(self, s):
        stack = []
        tokens = []
        number = ''
        for c in s:
            if c.isdigit():
                number += c
            else:
                if number:
                    tokens.append(number)
                    number = ''
                if c == '(':
                    stack.append(c)
                elif c == ')':
                    while len(stack) and stack[-1] != '(':
                        tokens.append(stack.pop())
                    stack.pop()
                elif c in self.calculator:
                    while len(stack) and self.priority(stack[-1]) >= self.priority(c):
                        tokens.append(stack.pop())
                    stack.append(c)
        if number:
            tokens.append(number)
        while len(stack):
            tokens.append(stack.pop())
        return tokens
    
    def priority(self, c):
        map = { '+' : 1,
                '-' : 1,
                '*' : 2,
                '/' : 2
              }
        return map.get(c, 0)
    
    def compute(self, tokens):
        stack = []
        for token in tokens:
            if token not in self.calculator:
                stack.append(int(token))
            else:
                x = stack.pop()
                y = stack.pop()
                stack.append(self.computeRPN(token, x, y))
        return stack[0]
    
    def computeRPN(self, token, x, y):
        map = { '+': lambda x, y: y + x,
                '-': lambda x, y: y - x,
                '*': lambda x, y: y * x,
                '/': lambda x, y: y * 1.0 / x
              }
        return map[token](x, y)
        
        

###Java

public class Solution {
    public int calculate(String s) {
        String[] tokens = toRPN(s).split("\\s+");
        String op = "+-";
        Stack<String> stack = new Stack<String>();
        for (int i = 0; i < tokens.length; i++) {
            if (!op.contains(tokens[i])) {
                stack.push(tokens[i]);
            } else {
                int a = Integer.parseInt(stack.pop());
                int b = Integer.parseInt(stack.pop());
                switch (tokens[i]) {
                    case "+":
                        stack.push(String.valueOf(a + b));
                        break;
                    case "-":
                        stack.push(String.valueOf(b - a));
                        break;
                    default:
                        break;
                }
            }
        }
        
        return Integer.parseInt(stack.pop());
    }
    
    public String toRPN(String s) {
        char[] arr = s.toCharArray();
        Stack<Character> stack = new Stack<Character>();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < arr.length; i++) {
            switch (arr[i]) {
                case '+':
                case '-':
                    while (!stack.isEmpty() && stack.peek() != '(') {
                        sb.append(" ");
                        sb.append(stack.pop());
                    }
                    sb.append(" ");
                    stack.push(arr[i]);
                    break;
                case '(':
                    stack.push(arr[i]);
                    break;
                case ')':
                    while (!stack.isEmpty() && stack.peek() != '(') {
                        sb.append(" ");
                        sb.append(stack.pop());
                    }
                    stack.pop();
                    break;
                case ' ':
                    break;
                default :
                    sb.append(arr[i]);
                    break;
            }
        }
        
        while (!stack.isEmpty()) {
            sb.append(" ");
            sb.append(stack.pop());
        }
        
        return sb.toString();
    }
}

###Points

表达式求值可以分解为下列两步完成:

1. 中缀表达式转为后缀表达式(逆波兰表达式)

2. 后缀表达式求值

以下内容来自百度百科:“后缀表达式”词条

中缀表达式转为后缀表达式的要点:

开始扫描;

数字时,加入后缀表达式;

运算符:

a. 若为 '(',入栈;

b. 若为 ')',则依次把栈中的的运算符加入后缀表达式中,直到出现'(',从栈中删除'(' ;

c. 若为 除括号外的其他运算符, 当其优先级高于除'('以外的栈顶运算符时,直接入栈。否则从栈顶开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到一个比它优先级低的或者遇到了一个左括号为止。
·当扫描的中缀表达式结束时,栈中的的所有运算符出栈;

后缀表达式求值的过程简述:

建立一个栈S

从左到右读表达式,如果读到操作数就将它压入栈S中

如果读到n元运算符(即需要参数个数为n的运算符)则取出由栈顶向下的n项按操作符运算,再将运算的结果代替原栈顶的n项,压入栈S中

如果后缀表达式未读完,则重复上面过程,最后输出栈顶的数值则为结束。

###Task2 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.

###python

Same code still works fine