前缀表达式(波兰表达式)转 后缀表达式(逆波兰表达式)(java实现)


前言

前缀表达式:就是我们常见的算术表达式,这里就以1+((2+3))*5)-5举例。
后缀表达式:上面式子对应的后缀表达式为 1 2 3 + 5 * + 5 - 不难看出后缀表达式没有括号,而真因后缀表达式的这个形式,很好的贴合了计算机底层的运算原理(栈)


一、转换思路

1、初始化一个队列suffixList(用于存放最终的后缀表达式), 初始化一个栈stringStack(用于存放运算符)
2、从左至右遍历中缀表达式
3、遇到运算数,压入suffixList中
4、遇到运算符,压入stringStack中
   1)若stringStack栈为空,或stringStack栈顶元素为“(”,则直接压入stringStack栈
   2)否则,若运算符优先级高于栈顶元素,直接压入栈
   3)否则,将stringStack栈顶元素弹出,压入到suffixList中,回到第4步重新比较
5、遇到括号“(”或“)”
   1)若为“(”,则直接压入stringStack栈
   2)若为“)”,则依次弹出stringStack中的运算符,压入suffixList中,直到遇到“(”为止,然后移除“(”         注意:这里是直接在stringStack中移除“(”!
6、遍历完毕后,将stringStack中剩余的元素依次弹出并压入到suffixList中,遍历输出队列suffixList即为算数表达式对应的后缀表达式(逆波兰表达式)

二、图片演示

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、代码实现

1、核心代码

代码如下(示例):

  //将中缀表达式转化为后缀表达式
    public static List<String> parseSuffixExpressionList(List<String> infixList) {
       // Stack<String> numberStack = new Stack<>(); //存放需计算的数字 (在整个过程中一直在进栈, 最终也是将这个栈放到一个ArrayList中 故可直接新建一个List 如下
        ArrayList<String> suffixList = new ArrayList<>();
        Stack<String> stringStack = new Stack<>(); //存放运算符号

        for (String s : infixList) {
            if (s.matches("\\d+")) { //正则表达式 匹配到是多位数
                suffixList.add(s);
            } else if (s.equals("(")) {
                stringStack.push(s);
            } else if (s.equals(")")) {
                while (!stringStack.peek().equals("(")) { //peek() 方法 查看栈顶元素 但不移除
                    suffixList.add(stringStack.pop()); //符号栈中弹出运算符加到list中 直到遇到符号(
                }
                stringStack.pop(); //将”(“ 弹出  消除括号
            } else {
                //当s的优先级小于stringStack栈顶的优先级 将stringStack栈顶的元素弹出并加入到suffixList中
                if (stringStack.size() > 0 && Operation.getValue(stringStack.peek()) >= Operation.getValue(s)) {
                    suffixList.add(stringStack.pop());
                }
                stringStack.push(s); //将s压入栈
            }
        }

        //将stringStack中剩余的运算符一次弹出并加入到suffixList中
        while (stringStack.size() != 0) {
            suffixList.add(stringStack.pop());
        }
        return suffixList; //放到List中 即为顺序输出 (若开始时创建的是两条栈,  则最终应该反转)
    }

2.完整代码

代码如下(示例):

package com.xx.stack;

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

/**
 * @author 谢鑫
 * @version 1.0
 */
public class InfixToSuffix {
    public static void main(String[] args) {
        String infixExpression = "1 + ( ( 2 + 3 ) * 5 ) - 5";
        List<String> infixList = getListString(infixExpression); //将中缀表达式放到list中
        System.out.println("中缀表达式对应的List");
        System.out.println(infixList);


        System.out.println("后缀表达式对应的List");
        List<String> suffixList = parseSuffixExpressionList(infixList);
        System.out.println(suffixList);

    }

    //将中缀表达式放到ArrayList中
    public static List<String> getListString(String infixExpression) {
        //将suffixExpression分割
        String[] split = infixExpression.split(" ");
        List<String> list = new ArrayList<>();
        for (String element : split) { ;
            list.add(element);
        }
        return list;
    }


    //将中缀表达式转化为后缀表达式
    public static List<String> parseSuffixExpressionList(List<String> infixList) {
       // Stack<String> numberStack = new Stack<>(); //存放需计算的数字 (在整个过程中一直在进栈, 最终也是将这个栈放到一个ArrayList中 故可直接新建一个List 如下
        ArrayList<String> suffixList = new ArrayList<>();
        Stack<String> stringStack = new Stack<>(); //存放运算符号

        for (String s : infixList) {
            if (s.matches("\\d+")) { //正则表达式 匹配到是多位数
                suffixList.add(s);
            } else if (s.equals("(")) {
                stringStack.push(s);
            } else if (s.equals(")")) {
                while (!stringStack.peek().equals("(")) { //peek() 方法 查看栈顶元素 但不移除
                    suffixList.add(stringStack.pop()); //符号栈中弹出运算符加到list中 直到遇到符号(
                }
                stringStack.pop(); //将”(“ 弹出  消除括号
            } else {
                //当s的优先级小于stringStack栈顶的优先级 将stringStack栈顶的元素弹出并加入到suffixList中
                if (stringStack.size() > 0 && Operation.getValue(stringStack.peek()) >= Operation.getValue(s)) {
                    suffixList.add(stringStack.pop());
                }
                stringStack.push(s); //将s压入栈
            }
        }

        //将stringStack中剩余的运算符一次弹出并加入到suffixList中
        while (stringStack.size() != 0) {
            suffixList.add(stringStack.pop());
        }
        return suffixList; //放到List中 即为顺序输出 (若开始时创建的是两条栈,  则最终应该反转)
    }
}

class                               Operation {
    private static int ADD = 1;
    private static int SUB = 1;
    private static int MUL = 2;
    private static int DIV = 2;

    public static  int getValue(String operation) {
        int result = 0;
        switch (operation) {
            case "+":
                result = ADD;
                break;
            case "-":
                result = SUB;
                break;
            case "*":
                result = MUL;
                break;
            case "/":
                result = DIV;
                break;
            default:
                System.out.println("出发处理该运算符!");
                break;
        }
        return result;
    }
}


总结

望纠正!

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值