下面题目是LeetCode算法:逆波兰表达式求值(java实现)
逆波兰表达式即后缀表达式。
题目:
有效的运算符包括 +
, -
, *
, /
。每个运算对象可以是整数,也可以是另一个逆波兰表达式、同时支持括号。(假设所有的数字均为整数,不考虑精度问题)
计算工具:
/** * 计算工具 * @author monkjavaer * @date 2018/9/13 14:35 */ public class CalculatorUtil { /** * 加 */ private static final String ADD = "+"; /** * 减 */ private static final String SUBTRACT = "-"; /** * 乘 */ private static final String MULTIPLICATION = "*"; /** * 除 */ private static final String DIVISION = "/"; /** * 左括号 */ private static final String LEFT_PARENTHESIS = "("; /** * 右括号 */ private static final String RIGHT_PARENTHESIS = ")"; /** * * 提供给外部的计算方法 * * @param expression 后缀表达式 * @return 计算结果 */ public static int calculation(Expression expression) throws Exception { List<String> list = getPostfix(expression); Stack<Integer> calculationStack = new Stack<>(); Integer operandRight; Integer operandLeft; for (String item : list) { if (ADD.equals(item)) { operandRight = calculationStack.pop(); operandLeft = calculationStack.pop(); calculationStack.push(operandLeft + operandRight); } else if (SUBTRACT.equals(item)) { operandRight = calculationStack.pop(); operandLeft = calculationStack.pop(); calculationStack.push(operandLeft - operandRight); } else if (MULTIPLICATION.equals(item)) { operandRight = calculationStack.pop(); operandLeft = calculationStack.pop(); calculationStack.push(operandLeft * operandRight); } else if (DIVISION.equals(item)) { operandRight = calculationStack.pop(); operandLeft = calculationStack.pop(); calculationStack.push(operandLeft / operandRight); } else { calculationStack.push(Integer.parseInt(item)); } } return calculationStack.pop(); } /** * 判断字符为运算符(+,-,*,/) * * @param c 输入字符 * @return */ private static boolean isOperator(char c) { return ADD.equals(String.valueOf(c)) || SUBTRACT.equals(String.valueOf(c)) || MULTIPLICATION.equals(String.valueOf(c)) || DIVISION.equals(String.valueOf(c)); } /** * 返回的是运算符的优先级 * * @param operator * @return */ private static int priority(Operator operator) { char operatorName = operator.getOperatorName(); if (ADD.equals(String.valueOf(operatorName)) || SUBTRACT.equals(String.valueOf(operatorName))) { return 1; } else if (MULTIPLICATION.equals(String.valueOf(operatorName)) || DIVISION.equals(String.valueOf(operatorName))) { return 2; } else { return 0; } } /** * 通过表达式获得后缀表达式 * * @param expression * @return */ private static List<String> getPostfix(Expression expression) throws Exception { /** * 操作符栈 */ Stack<Operator> operatorStack = new Stack<>(); /** * 存放后缀表达式 */ List<String> operandList = new ArrayList<>(); String expressionStr = expression.getExpressionStr(); for (int i = 0; i < expressionStr.length(); i++) { char oneChar = expressionStr.charAt(i); Operator operator = new Operator(); operator.setOperatorName(oneChar); //遇到操作数:直接输出(添加到后缀表达式中) if (Character.isDigit(oneChar)) { int num = oneChar - '0'; while (i + 1 < expressionStr.length() && Character.isDigit(expressionStr.charAt(i + 1))) { num = num * 10 + expressionStr.charAt(i + 1) - '0'; i++; } operandList.add(String.valueOf(num)); } else if (LEFT_PARENTHESIS.equals(String.valueOf(oneChar))) { //遇到左括号:将其入栈 operatorStack.push(operator); } else if (RIGHT_PARENTHESIS.equals(String.valueOf(oneChar))) { //遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。 while (!LEFT_PARENTHESIS.equals(String.valueOf(operatorStack.peek().getOperatorName()))) { operandList.add(String.valueOf(operatorStack.pop().getOperatorName())); } //然后弹出左括号 operatorStack.pop(); } else if (isOperator(oneChar)) { //遇到运算符 //栈为空时,直接入栈 if (operatorStack.isEmpty()) { operatorStack.push(operator); } else { // 如果读入的操作符为非")"且优先级比栈顶元素的优先级高或一样 if (priority(operatorStack.peek()) < priority(operator)) { operatorStack.push(operator); } else if (priority(operatorStack.peek()) >= priority(operator)) { operandList.add(String.valueOf(operatorStack.pop().getOperatorName())); operatorStack.push(operator); } } } } //最终将栈中的元素依次出栈。 while (!operatorStack.isEmpty()) { operandList.add(String.valueOf(operatorStack.pop().getOperatorName())); } System.out.println(operandList); return operandList; } }
表达式:
/** * 表达式 * * @author monkjavaer * @date 2018/9/12 19:42 */ public class Expression { /** * 表达式名字 */ private String name; /** * 表达式 */ private String expressionStr; /** * 表达式值 */ private int value; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getExpressionStr() { return expressionStr; } public void setExpressionStr(String expressionStr) { this.expressionStr = expressionStr; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } }
操作数:
/** * 操作数 * @author monkjavaer * @date 2018/9/12 19:43 */ public class Operand { /** * 操作数值 */ private Integer operandValue; public Integer getOperandValue() { return operandValue; } public void setOperandValue(Integer operandValue) { this.operandValue = operandValue; } }
运算符:
/** * 运算符 * * @author monkjavaer * @date 2018/9/12 19:43 */ public class Operator { /** * 运算符符号 */ private char operatorName; public char getOperatorName() { return operatorName; } public void setOperatorName(char operatorName) { this.operatorName = operatorName; } }
测试:
/** * @author monkjavaer * @date 2018/9/13 11:49 */ public class Test { public static void main(String[] args) { Expression expression = new Expression(); expression.setExpressionStr("4 +(13 - 5)"); try { System.out.println(CalculatorUtil.calculation(expression)); } catch (Exception e) { e.printStackTrace(); } } }