数据结构与算法 Java实现计算后缀表达式(逆波兰表达式)

前面我们介绍了什么是中缀、前缀和后缀表达式,还实现使用Java代码了中缀表达式转后缀表达式。这篇博客我们来介绍如何计算后缀表达式,并使用Java实现。

计算后缀表达式的流程:

  • 从左至右扫描表达式,遇到数字时,将数字压入堆栈。

  • 遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 和 栈顶元素),并将结果入栈。

  • 重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。

  • 代码示例:

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

public class Calculator {

    //存储运算符和优先值键值对
    static Map<Character, Integer> ops = new HashMap<>();
    static {
        //ops.put('(', 0);
        ops.put('+', 1);
        ops.put('-', 1);
        ops.put('*', 2);
        ops.put('/', 2);
    }

    public static Character getComputingResult(String expression){
        Stack<Character> tempStack = transferNifixExpressionToPostfixExpression(expression);
        Stack<Character> postfixExpressionStack = new Stack<>();
        //这里千万不能用size()遍历栈,因为栈的大小一直在变小。
        int count = tempStack.size();
        for (int i = 0;i < count;i ++){
            postfixExpressionStack.push(tempStack.pop());
        }
        Stack<Character> numberStack = new Stack<>();
        char temp = 0;
        int tempNum = 0;
        int fNumber = 0;
        int sNumber = 0;
        //处理从后缀表达式栈中弹出来的每个字符
        for (int i = 0;i < count;i ++){
            temp = postfixExpressionStack.pop();
            //如果字符为数字压入数字栈
            if(temp >= 48 && temp <= 57){
                numberStack.push(temp);
            }else {
                //这里需要注意运算数的前后顺序
                sNumber = Integer.valueOf(String.valueOf(numberStack.pop()));
                fNumber = Integer.valueOf(String.valueOf(numberStack.pop()));
                //如果计算结果超过9,需要另外实现
                if(temp == '+'){
                    tempNum = fNumber + sNumber;
                }else if(temp == '-'){
                    tempNum = fNumber - sNumber;
                }else if(temp == '*'){
                    tempNum = fNumber * sNumber;
                }else if(temp == '/'){
                    //这里需要注意,因为实现的是简易版计算,这里的计算结果如果为浮点类型自动被截取为整数
                    tempNum = fNumber / sNumber;
                }
                numberStack.push(String.valueOf(tempNum).charAt(0));
            }
        }
        return numberStack.pop();
    }

    private static Stack<Character> transferNifixExpressionToPostfixExpression(String nifixExpression){
        //存储表达式的中间结果
        Stack<Character> expStack = new Stack<>();
        //存储运算符
        Stack<Character> opStack = new Stack<>();
        //把中缀表达式字符串转换为字符数组
        char [] chars = new char[nifixExpression.length()];
        nifixExpression.getChars(0, nifixExpression.length(), chars, 0);
        //遍历数组,处理每一个表达式的字符
        for(int i = 0;i < chars.length;i ++){
            if(chars[i] >= 48 && chars[i] <= 57){
                expStack.push(chars[i]);
            }else {
                if(opStack.isEmpty() || opStack.peek() == '('){
                    opStack.push(chars[i]);
                }else {
                    if(chars[i] == '('){
                        opStack.push(chars[i]);
                    }else if(chars[i] == ')'){
                        while (opStack.peek() != '('){
                            expStack.push(opStack.pop());
                        }
                        opStack.pop();
                    }else {
                        while (ops.get(chars[i]) <= ops.get(opStack.peek())){
                            expStack.push(opStack.pop());
                            if(opStack.size() == 0)break;
                        }
                        opStack.push(chars[i]);
                    }
                }
            }
        }
        opStack.forEach(character -> {
            expStack.push(character);
        });
//        StringBuilder stringBuilder = new StringBuilder("");
//        expStack.forEach(character -> {
//            stringBuilder.append(character);
//        });
        return expStack;
    }

    public static void main(String[] args) {
        System.out.println(getComputingResult("(5+2)*1-4"));
    }
}
  • 输出:
3
  • 注意这里是实现的简易版计算器,全程计算只支持一位整数。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章