Leetcode224. Basic Calculator

先是看了discuss第一的一个tricky方法,用单个栈做。
更通用的应该是中缀表达式转前后缀表达式,两个栈的方法。参考前缀、中缀、后缀表达式(逆波兰表达式)

class Solution {
    public int calculate(String s) {
        Stack<Integer> stack = new Stack<>();
        int number=0;
        int ans = 0;
        int flag = 1;
        for(int i=0;i<s.length();i++){
            char c = s.charAt(i);
            if(c>='0' && c<='9'){
                number = number*10+(int)(c-'0');
            }else if(c=='+'){
                ans+=flag*number;
                number = 0;
                flag=1;
            }else if(c=='-'){
                ans+=flag*number;
                number = 0;
                flag = -1;
            }else if(c=='('){
                stack.push(ans);
                stack.push(flag);
                ans = 0;
                flag = 1;
            }else if(c==')'){
                ans+=flag*number;
                ans*=stack.pop();
                ans+=stack.pop();
                number=0;
                flag=1;
            }
        }
        if(number!=0) ans+=flag*number;
        return ans;
    }
}

Runtime: 5 ms, faster than 96.06% of Java online submissions for Basic Calculator.
Memory Usage: 39.2 MB, less than 46.44% of Java online submissions for Basic Calculator.
自己写了个通用方法,不过还有bug,先记录一下:

import java.util.*;

public class Calculator {
	public static void calculate(String s) {
		Stack<String> formula = transform(s);
		//中缀2-1+((2+3)×4)-5 ->后缀2 1 - 2 3 + 4 × + 5 -
		//后缀从左到右遍历,遇数压栈,遇运算符计算,结果压栈,继续遍历
		while(!formula.isEmpty()) System.out.println(formula.pop());//先不写利用后缀表达式计算的代码啦
	}
	private static Stack<String> transform(String s)  {
		//用一个表达式栈和一个运算符栈 把中缀表达式转化成后缀表达式
		//从左到右遍历,遇数压formula栈,遇operator做判断:
		//	operator为(,直接压栈
		//	operator栈空或栈顶为(,直接压栈;
		//	operator为),将op栈的op压入formula栈,直到遇到(。
		//	operator比op栈顶op优先级高,直接压栈;(这样出栈时高优先级就会在前面)
		//	operator不比op栈顶op优先级高,将高优先级和同等优先级的op从op栈压到formula栈;(这样可以保证正确运算顺序)
		Stack<String> formula = new Stack<>();
		Stack<Character> operator = new Stack<>();
		int i=0;
		for(;i<s.length();i++) {
			char bit = s.charAt(i);
			if(bit>='0'&&bit<='9') {
				int start=i;
				while(i<s.length()-1&&bit>='0'&&bit<='9') {
					i++;
					bit = s.charAt(i);
				}
				formula.push(s.substring(start, i));
				if(i==s.length()-1) break;
			}else if(bit=='(') operator.push(bit);
			else if(bit==')') {
				while(!operator.isEmpty()&&operator.peek()!='(') {
					String op = operator.pop().toString();
					formula.push(op);
				}
				operator.pop();
			}
			else if(operator.isEmpty()||operator.peek()=='(') operator.push(bit);
			else if(isPrior(bit,operator.peek())) operator.push(bit);
			else {//bit不是数字,不是(),且优先级不比op栈顶元素高
				while(!operator.isEmpty()&&!isPrior(bit,operator.peek())) {
					String op = operator.pop().toString();
					formula.push(op);
				}
			}
		}
		while(!operator.isEmpty()) {
			String op = operator.pop().toString();
			formula.push(op);
		}
		Stack<String> temp = new Stack<>();
		while(!formula.isEmpty()) {
			temp.push(formula.pop());
		}
		return temp;
	}

	private static boolean isPrior(char a,char b) {
		//只对加减乘除做了判断,如果加入新运算需要更新本函数
		if((a=='*'||a=='/')&&(b=='+'||b=='-')) return true;
		return false;
	}
	public static void main(String[] args) {
		calculate("1+((2+3)×4)-5");
	}
}
posted @ 2019-04-02 00:24  大胖子球花  阅读(85)  评论(0)    收藏  举报