完整代码实例-Java实现简单的逆波兰计算器

完整代码示例如下:

package DataStrcture.StackDemo;

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

public class PolanExpCaculator_copy {
    /**
     * 1.给定一个后缀表达式
     * 2.我们把后缀表达式通过  split分割字符, 赋值给String数组,
     * 3.遍历string数组, 把表达式的值一个个存储到集合中
     * 4.遍历集合, 遇到数字就入栈,遇到操作符就从栈中pop两个数进行运算,然后存入栈中,
     * 5.如此反复,栈中的唯一数就是表达式的结果了
     */
    public static void main(String[] args) {
        // (30+2)x5-6
        String suffixExp = "30 2 + 5 x 6 -";
        String infixExp = "( 30 + 2 ) x 5 - 6";
        PolanExpCaculator_copy polan = new PolanExpCaculator_copy();
        List<String> sufixList = polan.getList(suffixExp);
        List<String> InfixList = polan.getList(infixExp);
        System.out.println(sufixList);
        System.out.println("===============");

        int res = polan.calculate(sufixList);
        System.out.println("表达式的运算结果为: " + res);
        System.out.println("======================");
        System.out.println("中缀表达式: " + infixExp + "转为后缀表达式为: ");
        List<String> suffixExpression = polan.transferToSuffixExp(InfixList);
        System.out.println(suffixExpression);

        System.out.println("===============================");
        int res_1 = polan.calculate(suffixExpression);
        System.out.println("前缀表达式转为后缀表达式后的计算结果为: "+res_1);

    }

    //存储表达式到集合, 方便遍历表达式噢!
    public List<String> getList(String exp) {
        String[] expArry = exp.split(" ");

        ///新建集合对象
        List<String> list = new ArrayList<String>();
        for (String x : expArry) {
            list.add(x);
        }
        return list;
    }

    //开始计算
    public int calculate(List<String> list) {
        //存储运算结果
        int res = 0;
        ///栈,存储
        Stack<String> numStack = new Stack<String>();
        //循环list,取出元素
        for (String item : list) {
            //遇到数字入栈, 遇到操作符出栈
            if (item.matches("\\d+")) {
                numStack.push(item);
            } else {

                //遇到操作符,出栈做运算
                /**
                 * 在这下面我们应用了String-->int的方法
                 * 法1. int x = Integer.parseInt(str);
                 * 法2. 间接法: String-->Integer-->int
                 *   Integer integer = new Integer(str);
                 *   integer.intValue();
                 */
                int num_2 = Integer.parseInt(numStack.pop());
                int num_1 = Integer.parseInt(numStack.pop());

                if (item.equals("+")) {
                    res = num_1 + num_2;
                } else if (item.equals("-")) {
                    res = num_1 - num_2;
                } else if (item.equals("x")) {
                    res = num_1 * num_2;
                } else if (item.equals("/")) {
                    res = num_1 / num_2;
                } else {
                    throw new RuntimeException("操作符有误! ");
                }
                String res_str = "" + res; //每次计算完成一次都要把结果重新入栈,供下次别的计算
                numStack.push(res_str);
            }
        }
        int real_res = Integer.parseInt(numStack.pop());
        return real_res;
    }

    //规定运算符的优先级
    public static int getPrioity(String op) {
        if (op.equals("x") || op.equals("\\"))
            return 0;
        if (op.equals("+") || op.equals("-"))
            return -1;
        return 1;
    }

    ///中缀表达式转后缀表达式
    public List<String> transferToSuffixExp(List<String> list) {

        List<String> suffixExpList = new ArrayList<String>();// 存储后缀表达式的元素
        Stack<String> opStack = new Stack<String>();//存储符号栈

        //遍历集合
        for (String item : list) {
            if (item.matches("\\d+")) {//1. 数字的直接存到集合
                suffixExpList.add(item);
            } else if (item.equals("(")) {//2. 左括号直接压到栈中
                opStack.push(item);
            } else if (item.equals(")")) {
                //3. 遇见右括号,嘛也不管直接不停的出栈直到遇到了左括号
                while (!(opStack.peek().equals("("))) {
                    suffixExpList.add(opStack.pop());
                }
                opStack.pop();
                // 4.遇到的都是正儿八经的操作符,比较优先级后再决定入栈时机
            } else {
//                // 待插入栈的优先级大于栈顶操作符的优先级()
//                if (opStack.size() == 0 || (opStack.peek().equals("(") || getPrioity(item) > getPrioity(opStack.peek()))) {
//                    opStack.push(item);
//                } else {
                    ///待插入栈的优先级小于或者等于栈顶元素, 不停的出栈 (切记别忘了判空,更不要忘了忽略栈顶是括号的情况(是括号就直接入栈))
                    while (opStack.size() > 0 && getPrioity(opStack.peek()) >= getPrioity(item) && !(opStack.peek().equals("(") ))
                        suffixExpList.add(opStack.pop());
                    opStack.push(item);
//                }
            }
        }
        while (opStack.size() > 0)
            suffixExpList.add(opStack.pop());
        return suffixExpList;
    }
}

运行结果:

在这里插入图片描述

posted @ 2022-05-26 20:31  青松城  阅读(39)  评论(0编辑  收藏  举报