java实现逆波兰表(后缀)达式计算器(注释超详细)

如果不知道什么是前缀、中缀、后缀表达式的请参考此博客
https://blog.csdn.net/Antineutrino/article/details/6763722

1、将中缀表达式转换成列表,方便运算

/**
     * 将表达式放进list
     * @param expression
     * @return 中缀表达式列表
     */
    public List<String> parseInfixToList(String expression){
        List<String> list = new ArrayList<>();
        int index = 0;
        char c ;
        String str = "";
        do {
            c=expression.charAt(index);
            //如果是非数字,直接放进list
            if ( c<48 || c>57){
                list.add(""+c);
                index++;
            }
            //如果是数字,判断是否多位数
            else {
                //字符串拼接
                str = "";
                while (index < expression.length() && expression.charAt(index) >= 48 && expression.charAt(index) <= 57){
                    str +=c;
                    index++;

                }
                list.add(str);
            }
        }while (index < expression.length());

        return list;
    }

2、将中缀表达式转换成后缀表达式(重点)

/**
     * 将中缀表达式放进list,再将list转化为后缀表达式的list
     * @param list 中缀表达式的list
     * @return
     */
    public List<String> parseSuffixExpressionList(List<String> list){
        //工具1存放运算符
        Stack<String> operaStack = new Stack<>();
        //存储中间结果,为了简化操作,用list,list中的顺序就是逆波兰表达式
        List<String> resList = new ArrayList<>();

        //遍历list
        for (String item:list){
            //如果是数字,push to s2
            if (item.matches("\\d+")){
                resList.add(item);
            }
            else if (item.equals("(")){
                operaStack.push(item);
            }
            //when meet ")",则依次弹出s1栈顶的运算符,并且压入s2,知道遇到“(”为止
            else if (item.equals(")")){
                while (!operaStack.peek().equals("(")){
                    resList.add(operaStack.pop());
                }
                //此时将这一对括号丢弃
                operaStack.pop();
            }
            //when meet operator ,compare with the operator s1[top]
            //    else if cur operator's priority 》s1[top] ,push it to s1;
            //    else pop operator from s1[top] and push it to s2,than turn to if
            else {
                while (operaStack.size()>0 && Operator.getPriority(item) <= Operator.getPriority(operaStack.peek())){
                    resList.add(operaStack.pop());
                }
                operaStack.push(item);
            }
        }
        //将s1中的剩余运算符依次弹出并且加入到list
        while (operaStack.size() > 0){
            resList.add(operaStack.pop());
        }

        return resList;
    }

3、计算结果

/**
     * 计算结果
     * @param itemList 后缀表达式
     * @return 最后的运算结果
     */
    public static int calculate(List<String> itemList){
        //工具栈
        Stack<String> stack = new Stack<>();
        for (String elem:itemList){
            //如果是数字,则进栈
            if (elem.matches("\\d+")){
                stack.push(elem);
            }
            //如果是符号则出栈两个数进行运算
            else{
                int num1 = Integer.parseInt(stack.pop());
                int num2 = Integer.parseInt(stack.pop());
                //暂存结果
                int res = 0;
                if (elem.equals("+")){
                    res = num1+num2;
                }
                else if (elem.equals("-")){
                    res = num2-num1;
                }
                else if (elem.equals("*")){
                    res = num1*num2;
                }
                else if (elem.equals("/")){
                    res = num2/num1;
                }
                else {
                    throw new RuntimeException("运算符有误");
                }
                //将res入栈
                stack.push(String.valueOf(res));
            }
        }
        //遍历结束,留在栈中的就是最后结果
        return Integer.parseInt(stack.pop());
    }

除此以外,我们还需要一个自定义运算符优先级的类

class Operator{
    /**
     * 优先级
     */
    private static int PLUS = 1;
    private static int SUB = 1;
    private static int MUL = 2;
    private static int DIV = 2;

    public static int getPriority(String val){
        int priority = 0;
        switch (val){
            case "+":
                priority = 1;
                break;
            case "-":
                priority = 1;
                break;
            case "*":
                priority = 2;
                break;
            case "/":
                priority = 2;
                break;
            default:
                    break;
        }
        return priority;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值