四则运算表达式求值

一、题目

计算“9 + (3 - 1) × 3 + 10 / 2”字符串的值

二、解题思路

2.1 后缀表达法(RPN):

是一种不需要括号的后缀表达式法。
规则:
      从左到右便利表达式的每一个数字和符号,遇到数字就进栈,遇到符号就将处于栈顶两个数字出栈,进行计算,运算结果进栈,一直到最终获得结果。

2.2 中缀表达式转后缀表达式

规则:
从左到右便利中缀表达式的每一个数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或者优先级不高于栈顶符号则栈顶元素依次出栈并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。

三、Java代码实现

static String exp = "9 + (3-1) * 3 + 10 / 2";

public static void main(String[] args) {
	List<String> strings = splitExp(exp);
	List<String> rights = mid2Right(strings);

	Stack<String> stack = new Stack<>();

	for (String str : rights) {
		if (str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/")) {
			BigDecimal a1 = new BigDecimal(stack.pop());
			BigDecimal a2 = new BigDecimal(stack.pop());
			if (str.equals("+")) {
				stack.push(a2.add(a1).toString());
			} else if (str.equals("-"))  {
				stack.push(a2.subtract(a1).toString());
			} else if (str.equals("*"))  {
				stack.push(a2.multiply(a1).toString());
			} else {
				stack.push(a2.divide(a1).toString());
			}
		} else {
			stack.push(str);
		}
	}
	System.out.println(stack.pop());
}

/**
 * 中序转后序
 *
 * @param list
 * @return
 */
private static List<String> mid2Right(List<String> list) {
	List<String> rights = new ArrayList<>();
	Stack<String> stack = new Stack<>();
	for (String str : list) {
		if (str.equals("(")) {
			stack.push(str);
		} else if (str.equals("*") || str.equals("/")) {
			if (!stack.isEmpty()) {
				String pop = stack.pop();
				if (pop.equals("*") || pop.equals("/") || pop.equals("(")) {
					if (pop.equals("*") || pop.equals("/")) {
						rights.add(pop);
					}
				} else {
					stack.push(pop);
				}
			}
			stack.push(str);
		} else if (str.equals("+") || str.equals("-")) { // 由于+-优先级最低,匹配到最近的(并依次输出
			while (!stack.isEmpty()) {
				String pop = stack.pop();
				if (pop.equals("(")) {
					stack.push(pop);
					break;
				} else {
					rights.add(pop);
				}
			}
			stack.push(str);
		} else if (str.equals(")")) { // 匹配前面的(并依次出栈
			while (!stack.isEmpty()) {
				String pop = stack.pop();
				if (pop.equals("(")) {
					break;
				} else {
					rights.add(pop);
				}
			}
		} else {
			rights.add(str);
		}
	}

	while (!stack.isEmpty()) {
		rights.add(stack.pop());
	}
	return rights;
}

/**
 * 将表达式解析成数据片段
 *
 * @param exp
 * @return
 */
private static List<String> splitExp(String exp) {
	List<String> list = new ArrayList<>();
	StringBuilder temp = new StringBuilder();
	for (char c : exp.toCharArray()) {
		if (c == ' ') {
			continue;
		}
		if (c == '+' || c == '-' || c == '/' || c == '*' || c == '(' || c == ')') {
			add(list, temp.toString());
			temp.setLength(0);
			add(list, String.valueOf(c));
		} else {
			temp.append(c);
		}
	}
	add(list, temp.toString());

	return list;
}

/**
 * 放入数组
 *
 * @param list
 * @param str
 */
private static void add(List<String> list, String str) {
	if (str.length() > 0) {
		list.add(str);
	}
}

你可能感兴趣的:(数据结构)