Basic Calculator

问题描述

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. 

 

程序

第一种是普通的方法:先将表达式转成后缀表达式,然后再计算。(TLE)

将中缀表达式转为后缀表达式

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

开始扫描;

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

运算符:

a. 若为 '(',入栈;

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

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

 

public List<String> getPostfixExpressionList(String s) {
		List<String> list = new ArrayList<String>();

		// preprocess
		s = s.trim();
		char[] cc = s.toCharArray();
		String pro_s = "";
		Stack<String> st = new Stack<String>();

		for (int i = 0; i < cc.length; i++) {
			char c = cc[i];
			if (!Character.isDigit(c)) {
				pro_s += " " + c + " ";
			} else {
				pro_s += c;
			}
		}

		// operators priority
		HashMap<String, Integer> opMap = new HashMap<String, Integer>();
		opMap.put("+", 0);
		opMap.put("-", 0);
		opMap.put("*", 1);
		opMap.put("/", 1);

		String[] items = pro_s.split(" ");
		for (int i = 0; i < items.length; i++) {
			String item = items[i].trim();
			if (item.length() == 0) {
				continue;
			}
			if (item.equals("(")) {
				st.push(item);
			} else if (item.equals(")")) {
				while (!st.peek().equals("(")) {
					list.add(st.pop());
				}
				st.pop();
			} else if (opMap.containsKey(item)) {
				if (st.isEmpty() || st.peek().equals("(")
						|| opMap.get(st.peek()) < opMap.get(item)) {
					st.push(item);
				} else {
					while (!st.isEmpty() && !st.peek().equals("(")
							&& opMap.get(st.peek()) >= opMap.get(item)) {
						list.add(st.pop());
					}
					st.push(item);
				}
			} else {
				list.add(item);
			}
		}
		
		while (!st.isEmpty()) {
			list.add(st.pop());
		}
		
		return list;
	}

 

第二种是简化的方法,比较巧妙。

public class BasicCalculator {
	public int calculate(String s) {
		if (s == null || s.length() == 0) {
			return 0;
		}

		// transform to postfix expression
		BasicCalculatorII bs2 = new BasicCalculatorII();
		List<String> postExpressionList = bs2.getPostfixExpressionList(s);

		// calculate
		Stack<Integer> calStack = new Stack<Integer>();
		for (String ex : postExpressionList) {
			if (ex.equals("+")) {
				int n1 = calStack.pop();
				int n2 = calStack.pop();
				calStack.push(n1 + n2);
			} else if (ex.equals("-")) {
				int n1 = calStack.pop();
				int n2 = calStack.pop();
				calStack.push(n2 - n1);
			} else if (ex.equals("*")) {
				int n1 = calStack.pop();
				int n2 = calStack.pop();
				calStack.push(n2 * n1);
			} else if (ex.equals("/")) {
				int n1 = calStack.pop();
				int n2 = calStack.pop();
				calStack.push(n2 / n1);
			} else {
				calStack.push(Integer.valueOf(ex));
			}
		}

		return calStack.peek();
	}
	
	// only have +, - operators
	public int calculate2(String s) {
		if (s == null || s.length() == 0) {
			return 0;
		}

		s = s.trim();
		int res = 0, sign = 1;
		Stack<Integer> st = new Stack<Integer>();

		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (Character.isDigit(c)) {
				int cur = c - '0';
				while (i + 1 < s.length() && Character.isDigit(s.charAt(i + 1))) {
					cur = cur * 10 + (s.charAt(i + 1) - '0');
					++i;
				}
				res += sign * cur;
			} else if (c == '+') {
				sign = 1;
			} else if (c == '-') {
				sign = -1;
			} else if (c == '(') {
				st.push(res);
				res = 0;
				st.push(sign);
				sign = 1;
			} else if (c == ')') {
				res = st.pop() * res + st.pop();
				sign = 1;
			}
		}

		return res;
	}
}

 

posted @ 2015-07-15 12:26  Chapter  阅读(160)  评论(0编辑  收藏  举报