数据结构——栈(中缀表达式转后缀表达式)

波兰计算器——后缀表达式

对于一个表达式,在我们生活中是这样表示的: 1+((2+3)x4)-5 。也就是我们所说的中缀表达是 ,但是这对于计算机而言,这样计算是很复杂的,具体思路以及代码见上一篇博客:
栈实现计算器(中缀表达式)
所以,在计算器中使用的是后缀表达式——逆波兰表达式
那么如何实现从中缀表达式转换成后缀表达式呢?以下为实现思路:
中缀表达式转换成后缀表达式流程

代码:

package cn.littleworm.波兰计数器;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class PolandNotation {

    public static void main(String[] args) {
        String ex = "1+((2+3)*4)-5";
        List<String> list = toInfixExperssionList(ex);
        System.out.println(list);
        List<String> list1 = parseSuffixException(list);
        System.out.println(list1);

    }

    //首先将中缀表达式显示在list集合中
    public static List<String> toInfixExperssionList(String s){
        /*
            思路:
                1、传过来的是一个表达式字符串
                2、定义一个指针索引,用来遍历表达式
                3、要考虑的一个因素就是,如果数字,判断书是否是多位数

         */
        List<String> list = new ArrayList<>();
        int i = 0;  //定义指针索引
        String keeper;  //用于拼接字符串
        char ch;    //用来接收字符
        do {
            ch = s.charAt(i);
            //判断是否是符号
            if (ch<48||ch>57){  //证明不是数字
                list.add(ch+"");
                i++;
            }else {
                //先将keeper置为空
                keeper = "";
                while (i<s.length()&&(ch=s.charAt(i))>=48&&(ch=s.charAt(i))<=57){
                    keeper+=ch;
                    i++;    //自增
                }
                //加到集合中
                list.add(keeper);
            }

        }while (i<s.length());

        return list;
    }



  

    //将中缀表达式转换成后缀表达式
    public static List<String> parseSuffixException(List<String> listExc){
        //初始化符号栈
        Stack<String> s1 = new Stack<>();

        //创建一个list集合用来接收中间结果
        List<String> s2 = new ArrayList<>();

        //遍历listExc表达式
        for (String item : listExc) {
            //如果是一个数,直接加入
            if (item.matches("\\d+")){  //这里使用正则表达式,用来匹配多为数字
                s2.add(item);
            }else if (item.equals("(")){
                //如果是左括号,s1直接加入
                s1.push(item);
            }else if (item.equals(")")){
                //如果是左括号,依次弹出符号栈s1中的运算符,并压入到s2中,直到遇到右括号“(”
                // 将这一对括号全部丢掉
                while (!"(".equals(s1.peek())){
                    String pop = s1.pop();
                    s2.add(pop);
                }
                //当执行完上面的循环之后,栈顶指针就是指向左括号,所以要将左括号弹出去
                s1.pop();
            }else {
                //如果是符号
                //现在要判断当前符号的优先级是否小于等于栈顶符号,所以这时需一个比较优先级的方法
                while (s1.size()>0&&Operation.getValue(s1.peek())>=Operation.getValue(item)){
                    String pop = s1.pop();
                    s2.add(pop);
                }

                //如果当前运算符小于或者是符号栈为空
                s1.push(item);
            }

        }
        //当上面的循环都结束了,这时将符号栈中的数据依次pop出,并添加到s2中
        while (s1.size()!=0){
            String pop = s1.pop();
            s2.add(pop);
        }
        return s2;

    }

}
//内部类,来判断运算符号的优先级
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;
    }


}

结果展示:

结果展示

注:在其他的资料中,都是初始化两个栈,一个是符号栈,一个是数据栈,执行到最后的时候,要将数据栈倒叙输出就是后缀表达式了,但是在本篇博客中对于数据栈使用list集合来代替,因为list集合比栈更容易操作!!

发布了24 篇原创文章 · 获赞 5 · 访问量 2072

猜你喜欢

转载自blog.csdn.net/weixin_43288447/article/details/103979489