中缀表达式转换成逆波兰表达式(后缀表达式)

中缀表达式转换成逆波兰表达式

1.定义

逆波兰表达式又叫做后缀表达式。逆波兰表示法是波兰逻辑学家・卢卡西维兹(J・ Lukasewicz)于1929年首先提出的一种表达式的表示方法 。后来,人们就把用这种表示法写出的表达式称作“逆波兰表达式”。逆波兰表达式把运算量写在前面,把算符写在后面。

2.思路分析

  1. 首先要先将字符串分割成数组,方便操作。

  2. 如果是数字先暂时存储起来,如果是多位数 直接拼接。

  3. 定义方法,1.判断是否是操作符 2.操作符的优先级。一个零时存储操作符的栈

  4. 遍历数组,如果是数值直接存起来。

  5. 如果是操作符就跟栈顶比较。比他大直接入栈。

  6. 如果是左括号也直接进栈。

  7. 如果小于等于栈顶直接弹栈直到找到优先级比它高的,或者碰到左括号 在停下来。

  8. 如果碰到右括号弹栈,直到遇到左括号。

  9. 遍历完数组,将栈中的元素全部弹出

3.实现代码

public class TransformSuffix {

    public List<String> transform(String expression) {
        //匹配数字或者小数点
        Pattern pattern = Pattern.compile("[0-9]|\\.");
        //存储零时转好的中缀表达式
        List<String> listInfix = new ArrayList<String>();
        //存储转完的后缀表达式
        List<String> listSuffix = new ArrayList<String>();
        Stack<String> operator = new Stack<String>();
        //如果有多个数字,使用stringBuffer进行拼接
        StringBuffer str = new StringBuffer();


        //遍历字符串 把字符串转成数组方便后面操作。
        //1.遇到数字放到str里面 方便拼接
        for (int i = 0; i < expression.length(); i++) {
            //每次遍历一位
            String temp = expression.substring(i, i + 1);
            //判断是否是数字或者小数点
            if (pattern.matcher(temp).matches()) {
                str.append(temp);
                if (i == expression.length() - 1) {
                    listInfix.add(str.toString());
                }
                continue;
            }
            //判断str中有无数字如果有再添加。防止添加到空字符串
            if (str.length()!=0){
                listInfix.add(str.toString());
            }
            //清空字符串
            str.delete(0, str.length());
            //如果是操作符直接添加到数组中
            if (isOperator(temp)) {
                listInfix.add(temp);
            }
        }

        /*
            遍历刚才准备好的数组将数组中的中缀表达式转换成后缀表达式。
         */
        for (int i = 0; i < listInfix.size(); i++) {
            //每次读取一个元素
            String e = listInfix.get(i);
            //判断是否是操作符
            if (this.isOperator(e)) {

                //如果操作符栈是空的直接push进去
                if (operator.isEmpty()) {
                    operator.push(e);
                    continue;
                }
                //如果是左括号push
                if (e.equals("(")) {
                    operator.push(e);
                    continue;
                }
                //如果是右括号将操作符栈中的元素pop到右元素的位置
                if (e.equals(")")) {
                    while (!operator.peek().equals("(")) {
                        listSuffix.add(operator.pop());
                    }
                    operator.pop();
                    continue;
                }
                //如果当前的操作符优先级比栈顶优先级高 直接push到栈中
                if (priority(e) > priority(operator.peek())) {
                    operator.push(e);
                    continue;
                }
                //如果当前操作符优先级比栈顶操作符小于或者等于。弹出栈中的操作符直达碰到等级比他高的操作符
                while (true) {
                    if (operator.isEmpty()) {
                        break;
                    }
                    if (operator.peek().equals("(")){
                        break;
                    }


                    if (priority(e) <= priority(operator.peek())) {
                        listSuffix.add(operator.pop());
                    }

                }

                operator.add(e);
            }
            //如果不是操作符直接将元素添加到数组中
            if (!isOperator(e)) {
                listSuffix.add(e);
            }




        }

        //遍历完数组,直接将栈中的所有元素弹出
        while (true) {
            if (operator.isEmpty()) {
                break;
            }
            listSuffix.add(operator.pop());

        }
        //返回最终的结果
        return listSuffix;
    }



    /*
            判断是不是操作符
     */
    private boolean isOperator(String v) {
        if (v.equals("(") || v.equals(")") || v.equals("+") || v.equals("-") || v.equals("*") || v.equals("/")) {
            return true;
        }
        return false;
    }

    /*
            判断操作符的优先级
     */
    private int priority(String ope) {
        switch (ope) {
            case "+":
                return 1;
            case "-":
                return 1;
            case "*":
                return 2;
            case "/":
                return 2;
            case "(":
                return 0;
            case ")":
                return 0;
            default:
                throw new RuntimeException("运算符有误");
        }
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值