后缀表达式模拟逆波兰计算器详解

后缀表达式模拟逆波兰计算器详解

思路分析

  1. 先将一个表达式,即要计算的式子,也就是中缀表达式,转换为后缀表达式,每一个字符中间用空格隔开,方便字符串的分割
  2. 将后缀表达式按照空格分割后存储到集合中,集合很方便遍历、存和取
  3. 定义堆栈用来辅助计算
  4. 然后遍历集合,如果取到的是数字,则直接入栈,如果取到的是运算符,则进行相应的运算
  5. 将每次计算的结果再入栈
  6. 集合中所有元素遍历完毕后,堆栈中存储的是计算的结果,返回即可
  7. 源码及分析如下

源码及详解

public static void main(String[] args) {
        //模拟逆波兰计算机  例如计算 (3 + 4) * 5 - 6 ,其对应的后缀表达式为3 4 + 5 * 6 -
        //已知后缀表达式,中间用空格隔开,方便分割
        String expression = "(35 + 4) * 52 - 66";
        String suffixExpression = "35 4 + 52 * 66 -";
        //测试分割的方法
        List<String> listString = getListString(suffixExpression);
        //System.out.println(listString);
        //测试OK
        int res = calculate(listString);
        System.out.println(expression + " = " + res);
    }

    //编写一个方法将后缀表达式中的所有字符分割并存储在一个ArrayList集合中

    /**
     * 
     * @param suffixExpression 后缀表达式
     * @return                 拆分的结果
     */
    public static List<String> getListString(String suffixExpression) {
        //定义一个集合保存各个字符
        ArrayList<String> list = new ArrayList<>();
        //将后缀表达式按照空格分割
        String[] strings = suffixExpression.split(" ");
        //将分割后的字符串加入到集合
        for (String string : strings) {
            list.add(string);
        }
        return list;
    }

    /**
     * 编写后缀表达式的计算方法
     *
     * @param list 集合中保存要计算的数字和操作符
     * @return 计算的结果
     */
    public static int calculate(List<String> list) {
        //定义栈用来辅助计算
        Stack<String> stack = new Stack<>();
        //遍历集合
        for (String item : list) {
            //使用正则判断遍历出的是数字还是符号
            if (item.matches("\\d+")) {
                //如果是数字,则直接入栈
                stack.push(item);
            } else {
                //如果是符号,则从栈中弹出两个数进行计算
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                //调用计算的方法
                int res = calculateByNumAndOperation(num2, num1, item.charAt(0));
                //将计算的结果再入栈
                stack.push(res + "");
            }
        }
        //运算结束后留在栈底的就是计算的结果,返回即可
        return Integer.parseInt(stack.pop());
    }

    /**
     * 通过数字和操作符计算的方法
     *
     * @param num1      数字1
     * @param num2      数字2
     * @param operation 运算符
     * @return 计算的结果
     */
    public static int calculateByNumAndOperation(int num1, int num2, char operation) {
        //定义变量保存运算返回的结果
        int res = 0;
        switch (operation) {
            case '+':
                res = num1 + num2;
                break;
            //减法注意运算顺序
            case '-':
                res = num2 - num1;
                break;
            case '*':
                res = num1 * num2;
                break;
            case '/':
                //除法也要注意运算顺序
                res = num2 / num1;
                break;
            default:
                throw new RuntimeException("运算符有误~~");
        }
        return res;
    }
posted @ 2021-05-28 21:14  mx_info  阅读(72)  评论(0)    收藏  举报