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;

	}

}

 

你可能感兴趣的:(ca)