四方显神

导航

数据结构006_逆波兰计算器分析和实现

前缀表达式也叫波兰表达式。后缀表达式也叫逆波兰表达式。

逆波兰表达式实现计算器:

package com.njcx.test3;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class PolandNotation {

    /**
     * 逆波兰计算器 1.输入一个逆波兰表达式(后缀表达式),使用栈(stack),计算其结果 2.支持小括号和多位数
     * 
     * 从左到右扫描表达式,遇到数字,就把数字压入堆栈。 遇到运算符,弹出栈顶的两个数,用运算符对他们做相应的计算(次顶元素和栈顶元素),并将结果入栈。
     * 重复上述步骤直到表达式最右端,最后运算得出的值即为表达式的结果。
     */
    public static void main(String[] args) {
        // 先定义一个逆波兰表达式 (3+4)*5-6 -> 3 4 + 5 * 6 -
        String suffixExpression = "3 4 + 5 * 6 -";
        // 为了方便,逆波兰表达式中数字和符号用空格隔开
        // 思路
        // 1.先将suffixExpression放到arrayList中
        // 2.将ArrayList传给一个方法,遍历ArrayList配合栈完成计算
        List<String> rpnList = getListString(suffixExpression);
        System.out.println("rpnList = " + rpnList);

        int res = calculate(rpnList);
        System.out.println("计算结果是=" + res);
    }

    // 依次将一个逆波兰表达式的数据和运算符放入到ArrayList中,这样就不需要设置一个索引一个一个扫描这个表达式了
    public static List<String> getListString(String suffixExpression) {
        // 将suffixExpression分割
        String[] split = suffixExpression.split(" ");
        List<String> list = new ArrayList<String>();
        for (String elem : split) {
            list.add(elem);
        }
        return list;
    }

    // 完成对逆波兰表达式的步骤
    /**
     * 从左到右扫描表达式,遇到数字,就把数字压入堆栈。 遇到运算符,弹出栈顶的两个数, 用运算符对他们做相应的计算(次顶元素和栈顶元素),并将结果入栈。
     * 重复上述步骤直到表达式最右端,最后运算得出的值即为表达式的结果。
     */
    public static int calculate(List<String> list) {
        // 创建栈,只需要一个栈即可
        Stack<String> stack = new Stack<String>();
        // 遍历list
        for (String item : list) {
            // 这里使用一个正则表达式来取到数
            if (item.matches("\\d+")) { // 匹配的是多位数
                // 入栈
                stack.push(item);
            } else {
                // pop出两个数并运算再入栈
                int num2 = Integer.parseInt(stack.pop());// 栈顶元素
                int num1 = Integer.parseInt(stack.pop());// 次顶元素
                int res = 0;
                if (item.equals("+")) {
                    res = num1 + num2;
                } else if (item.equals("-")) {
                    res = num1 - num2;// 后弹的数-先弹的数
                } else if (item.equals("*")) {
                    res = num1 * num2;
                } else if (item.equals("/")) {
                    res = num1 / num2;
                } else {
                    throw new RuntimeException("运算符无法识别");
                }
                // 把运算结果入栈
                stack.push("" + res);// 把整数转字符串的操作
            }
        }
        // 最后留在栈里的就是我们的计算结果
        return Integer.parseInt(stack.pop());
    }

}

 

posted on 2020-09-21 19:38  szdbjooo  阅读(129)  评论(0编辑  收藏  举报