在现实生活中大家对于计算使用都是中缀表达式(nifix expression),如但是在计算机中表达式常常是以后缀表达式(postfix expression),又称逆波兰表达式(reverse Polish notation, RPN ).
例如:中缀表达式 1+((2+3)*4)-5
逆波兰表达式: 1 2 3 + 4 * + 5
操作符优先级
运算符优先级+ -1* /2(3(入栈后变为最低) 从左到右依次扫描中缀表达式如果输入带当前元素为 数字 ,直接输出到输出带中.如果输入带当前元素为 运算符 如果当前操作符堆栈为 空, 不管是什么运算符都直接push压入堆栈中.如果当前输入带操作符为 ‘)’,一直pop弹出栈顶元素到输出带中,直到遇到’(’ tip: 括号不输出如果当前输入带操作符不为’)’ 如果操作符堆栈中栈顶运算符的优先级 大于等于 输入带当前运算符优先级,则将操作符堆栈栈顶pop弹出,并输出到输出带中,直到栈顶优先级 小于 当前优先级如果操作符堆栈中栈顶运算符的优先级 小于 输入带当前运算符优先级,则将当前运算符push压栈 当输入带扫描完成,将操作符堆栈中剩余运算符pop弹出到输出带中例如对于 1 2 3 + 4 * + 5
对输入带从左到右依次扫描如果 输入带当前元素为数字,将其push压入运算数堆栈如果 输入带当前元素为运算符,取出运算数堆栈栈顶的两个元素,第一个栈顶元素为右运算数,第二个栈顶元素为左运算数,再将运算结果压入栈顶扫描结束后,运算数堆栈剩余的一个元素就是结果 例如 1+((2+3)4)-5
例:1 2 3 + 4 * + 5 -
Java版本
public class ReversePolishNotation { // integer bigger means higher priority private static Map<String, Integer> priority = new HashMap<>(); //set the base priority static { priority.put("(", 4); priority.put("*", 3); priority.put("/", 3); priority.put("-", 2); priority.put("+", 2); } public static Integer reversePolish(String infixNotation) { List<String> newInfixNotation = getNewInfixNotation(infixNotation); List<String> prefixNotation = transFromInfixToPrefix(newInfixNotation); Integer result = calculate(prefixNotation); return result; } //transform (string)infixNotation to (list<string>)infixNotation public static List<String> getNewInfixNotation(String infixNotation) { List<String> newInfixNotation = new ArrayList<>(); for (int cnt = 0; cnt < infixNotation.length(); ++cnt) { char nowChar = infixNotation.charAt(cnt); //find the continuous digits and combine if(Character.isDigit(nowChar)) { StringBuffer temp = new StringBuffer(); while (cnt < infixNotation.length() && Character.isDigit(infixNotation.charAt(cnt))) { temp.append(infixNotation.charAt(cnt)); ++cnt; } --cnt; newInfixNotation.add(temp.toString()); } //else if nowChar is operator else if(nowChar != ' ') { newInfixNotation.add(String.valueOf(nowChar)); } } return newInfixNotation; } //transform infixNotation to prefixNotation public static List<String> transFromInfixToPrefix(List<String> infixNotation) { List<String> result = new ArrayList<>(); Stack<String> operator = new Stack<>(); for (String s : infixNotation) { //if its not digit if(!Character.isDigit(s.charAt(0))) { if(!operator.isEmpty()) { if(s.equals(")")) { while (!operator.isEmpty() && !operator.peek().equals("(")) { result.add(operator.pop()); } operator.pop(); } else { while (!operator.isEmpty() && priority.get(operator.peek()) >= priority.get(s) && !operator.peek().equals("(")) { result.add(operator.pop()); } operator.push(s); } } else { operator.push(s); } } // if its digit else {result.add(s);} } while (!operator.isEmpty()) {result.add(operator.pop());} return result; } // calculate the result by prefixNotation public static Integer calculate(List<String> prefixNotation) { Stack<Integer> calculateStack = new Stack<>(); for (String str : prefixNotation) { if(Character.isDigit(str.charAt(0))) { calculateStack.push(Integer.parseInt(str)); } else { Integer after = calculateStack.pop(); Integer before = calculateStack.pop(); Integer result = 0; switch (str) { case "+": result = before + after; break; case "-": result = before - after; break; case "*": result = before * after; break; case "/": result = before / after; break; } calculateStack.push(result); } } return calculateStack.pop(); } public static void main(String[] args) { String temp="1+((2+3)*4)-5"; System.out.println(reversePolish(temp));//结果是16正确 } }