中缀表达式转化为后缀表达式

问题遇到的现象和发生背景

中缀表达式转化为后缀表达式
报错:Exception in thread "main" java.util.EmptyStackException
at java.base/java.util.Stack.peek(Stack.java:102)
at java.base/java.util.Stack.pop(Stack.java:84)
at Stack.PolandNotation.parseSuffixExpressionList(PolandNotation.java:56)
at Stack.PolandNotation.main(PolandNotation.java:18)

我想要达到的结果

好兄弟们帮我看看,为啥比着敲都报错啊,我已经看了两个小时了。。。


```java

package Stack;

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

public class PolandNotation {
    public static void main(String[] args) {
        /*添加一个将中缀表达式转换成后缀表达式的功能:
        1。因为直接对string进行操作不方便,因此将"1+((2+3)*4)-5" 转成中缀表达式对应的List
        即 "1+((2+3)*4)-5" --> ArrayList [1, +, (, (, 2, +, 3, ), *, 4, ), -, 5]*/
        String expression = "1+((2+3)*4)-5";
        List<String> List01 = toInfixExpressionList(expression);
        System.out.println(List01);
         /*2.将中缀表达式的List --> 后缀表达式的List
        即 ArrayList [1, +, (, (, 2, +, 3, ), *, 4, ), -, 5] --> ArrayList[1, 2, 3, +, 4, *, +, 5, –]*/

        List<String> List03 = parseSuffixExpressionList(List01);
        System.out.println(List03);



        /*先定义一个逆波兰表达式
        (3+4)×5-6 对应的后缀表达式就是: 3 4 + 5 * 6 -
         为了说明方便,逆波兰表达式的数字和符号用空格隔开*/
        //String suffixExpression = "30 4 + 5 * 6 -";
        /*IDEA:1、先把 "3 4 + 5 × 6 -" 放入ArrayList中 (为了不用一一扫描)
               2、将ArrayList传递一个方法,遍历AL 再配合栈完成计算*/

        //List<String> rpnList = getListString(suffixExpression);
        //System.out.println("rpnList=" + rpnList);

        // int res = calculate(rpnList);
        //System.out.println("res=" + res);


    }

    //2.将中缀表达式的List --> 后缀表达式的List:
    public static List<String> parseSuffixExpressionList(List<String> ls) {
        Stack<String> s1 = new Stack<String>();//符号栈 s1
        //由于s2没有pop操作,而且后面还有逆序输出,所以不用Stack<String>s1,改用List<String>
        List<String> s2 = new ArrayList<String>();//储存中间结果List s2

        for (String item : ls) {//遍历ls
            if (item.matches("\\d+")) {// 1⃣️if num
                s2.add(item);
            } else if (item.equals("(")) {
                s1.push(item);
            } else if (item.equals(")")) {
          /*如果是右括号“)”,则依次弹出s1栈顶的运算符,并压入s2,
            直到遇到左括号为止,此时将这一对括号丢弃*/
                while (s1.size() != 0 && !s1.peek().equals("(")) {
                    s2.add(s1.pop());
                }
                s1.pop();//消除小括号
            } else {//2⃣️ if operation
                //当item优先级 <= peek优先级 将s1栈顶的运算符弹出并压入到s2中,再次转到(4-1)与s1中新的栈顶运算符相比较;
                while (s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item)){
                    s2.add(s1.pop());
                }
                s1.push(item);//若优先级比栈顶运算符的高,将运算符压入s1;
            }
        }
        //将最后s1剩余的运算符加入s2
        while(s1.size() != 0){
            s2.add(s1.pop());
        }
        return s2;//以为是存放进List,所以按顺序输出就是结果了
    }


    //1.将中缀表达式转成List的方法:
    public static List<String> toInfixExpressionList(String s) {
        List<String> ls = new ArrayList<String>();
        int i = 0;//表示一个指针,用于遍历中缀里的字符串
        String str;//多位数的拼接
        char ch;//遍历到字符就放入ch
        do {
            if ((ch = s.charAt(i)) < 48 || (ch = s.charAt(i)) > 57) {//不是数字就加入ls
                ls.add("" + ch);
                i++;
            } else {//如果是数字,还要判断是不是多位数
                str = " ";//先清空一下字符串
                while (i < s.length() && (ch = s.charAt(i)) >= 48 && (ch = s.charAt(i)) <= 57) {
                    str += ch;//拼接
                    i++;
                }
                ls.add(str);
            }
        } while (i < s.length());
        return ls;
    }

        //将逆波兰表达式放入AL中
    public static List<String> getListString(String suffixExpression) {
        String[] split = suffixExpression.split(" ");//分割逆波兰
        List<String> list = new ArrayList<String>();
        for (String ele : split) {
            list.add(ele);
        }
        return list;
    }

    /*逆波兰表达式求值步骤如下:
    1.从左至右扫描(go through),将3和4压入堆栈;
    2.遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素),计算出3+4的值,得7,再将7入栈;
    3.将5入栈;
    4.接下来是×运算符,因此弹出5和7,计算出7×5=35,将35入栈;
    5.将6入栈;
    6.最后是-运算符,计算出35-6的值,即29,由此得出最终结果 */
    public static int calculate(List<String> ls) {
        Stack<String> stack01 = new Stack<String>();//只需new一个stack
        for (String item : ls) {//go through the list
            //使用正则表达式来取数
            if (item.matches("\\d+")) { //匹配的是多位数
                stack01.push(item);//如果是是数就直接入栈
            } else {//如果不是就pop两个数,运算后,再入栈
                int num1 = Integer.parseInt(stack01.pop().trim());
                int num2 = Integer.parseInt(stack01.pop().trim());
                int res = 0;
                if (item.equals("+")) {
                    res = num2 + num1;
                } else if (item.equals("-")) {
                    res = num2 - num1;
                } else if (item.equals("*")) {
                    res = num2 * num1;
                } else if (item.equals("/")) {
                    res = num2 / num1;
                } else {
                    throw new RuntimeException("运算符有误!");
                }
                //把res入栈
                stack01.push(res + " ");//把int --》 char
            }
        }
        //最后的res就是结果
        return Integer.parseInt(stack01.pop());

    }
}

//priority class
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("the operation doesn't exist!");
                break;
        }
        return result;
    }
}

```