leetcode算法学习----逆波兰表达式求值(后缀表达式)

下面题目是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();
        }
    }

}

 

  

 

 

posted @ 2018-10-30 21:05  monkjavaer  阅读(685)  评论(0编辑  收藏  举报