中缀表达式转后缀表示式

实现综合计算器

package com.bzw.stack;

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

public class calculator {
    public static void main(String[] args) {

        //1+((2+3)*4)-5
        String expression = "1 + ( ( 2 + 3 ) * 4 ) - 5";
        List<String> list = getListString(expression);
//        for (String item : list){
//            System.out.println(item);
//        }

        Stack<String> stack = new Stack<>();

        stack = toReversePolish(list);

//        while (!stack.empty()){
//            System.out.println(stack.pop());
//        }

        System.out.println(reversePolishCalcultor(stack));
    }

    //为了表示方便,将字符串转成数组
    public static List getListString(String str){
        ArrayList<String> list = new ArrayList<>();
        String[] split = str.split(" ");
        for (String item : split){
            list.add(item);
        }
        return list;
    }

    //中缀转后缀
    public static Stack toReversePolish(List<String> list){
        Stack<String> stack1 = new Stack<>();   //符号栈
        Stack<String> stack2 = new Stack<>();   //中间结果栈
        Stack<String> stack3 = new Stack<>();   //最终结果栈

        for (String item : list){
            if (item.matches("\\d+")){  //正则表达式,匹配多位数。
                stack2.push(item);
            }
            else if (item.equals("(")){
                stack1.push(item);
            }
            else if (item.equals("+") || item.equals("-") || item.equals("*") || item.equals("/")){
                if (stack1.empty() ||stack1.peek().equals("(")){
                    stack1.push(item);
                }
                else {
                    String top = stack1.peek();
                    while (getPriority(top) >= getPriority(item)){//item的优先级如果大于栈顶元素优先级,直接压栈;反之执行while循环

                            String temp = stack1.pop();
                            stack2.push(temp);
                            if (stack1.empty()){
                                break;
                            }
                            top = stack1.peek();


                    }
                    stack1.push(item);
                }

            }
            else if (item.equals(")")){
                while (true){
                    if (stack1.peek().equals("(")){
                        stack1.pop();
                        break;
                    }
                    stack2.push(stack1.pop());
                }
            }
        }
        while (!stack1.empty()){
            stack2.push(stack1.pop());
        }
        //stack2 的逆序即是逆波兰式
        while (!stack2.empty()){
            stack3.push(stack2.pop());
        }
        return stack3;
    }

    public static int reversePolishCalcultor(Stack<String> stack){
        int res = 0;
        Stack<String> stack1 = new Stack<>();
        for(int i=stack.size() -1;i>=0;i--){    //栈底元素是stack.get(0);如果直接用foreach遍历的话,
            String item = stack.get(i);         //不仅会报java.util.ConcurrentModificationException错误;而且逻辑也不对
            if (item.matches("\\d+")){
                stack1.push(item);
            }
            else {
                int res1 = Integer.parseInt(stack1.pop());
                int res2 = Integer.parseInt(stack1.pop());
                if (item.equals("+")){
                     res = res1 + res2;
                }
                if (item.equals("-")){
                    res = res2 - res1;
                }
                if (item.equals("*")){
                    res = res1 * res2;
                }
                if (item.equals("/")){
                    res = res2 / res1;
                }
                String str = Integer.toString(res);
                stack1.push(str);
            }
        }
        return Integer.parseInt(stack1.pop());
    }
    public static int getPriority(String str1){
        if (str1.equals("+") || str1.equals("-")){
            return 0;
        }
        if (str1.equals("*") || str1.equals("/")){
            return 1;
        }
        else return 2;  //这里只考虑 +,-,*,/ 其他运算符不做讨论
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值