10、栈-中缀表达式转后缀表达式

来源:https://www.bilibili.com/video/BV1B4411H76f?p=39

一、思路

1、初始化同样设置两个栈,符号栈s1和结果栈s2;

2、从左到右扫描中缀表达式;

3、遇到数据,直接入栈s2;

4、遇到符号:

  4.1、如果s1为空,或者s1的栈顶符号为 "(" ,也就是左括号,直接入栈s1

  4.2、如果当前符号比s1栈顶的符号优先级高,直接入栈s1

  4.3、否则,将s1栈顶的那个运算符弹出,压入到s2,然后回到4.1继续比较,直到入栈。

5、遇到括号:

  5.1、左括号"("直接入栈s1

  5.2、右括号")",将s1中的运算符依次弹出,入栈s2,直到遇到左括号"(",此时将括号删除

6、重复步骤2-5,直到表达式结束

7、将s1中剩余的符号弹出,入栈s2

8、s2中的内容依次弹出,逆序,则为后缀表达式

二、实现

1、根据原始字符串的到中缀表达式对应的数组,要注意多位数的存在

 1     //根据原始字符串得到中缀表达式的字符串
 2     public static List getInfixArray(String s){
 3         List list = new ArrayList<>();
 4         int i = 0;//遍历原始的表达式
 5         char c;//获取当前位置的字符
 6         String keepNum;//如果是多位数可以用来拼接
 7         while (true){
 8             if((c = s.charAt(i)) < 48 || (c = s.charAt(i)) > 57){
 9                 //不是数字
10                 list.add(""+c);
11                 i++;
12             }else {
13                 keepNum = "";
14                 while (i < s.length() && (c = s.charAt(i))>= 48 && (c = s.charAt(i)) <= 57 ){
15                     keepNum += c;
16                     i++;
17                 }
18                 list.add(""+keepNum);
19             }
20             if(i > s.length() - 1){
21                 break;
22             }
23         }
24         return list;
25     }

测试

1         //原始表达式
2         String expression = "1+((2+3)*4)-5";
3         //根据原始表达式得到中缀表达式
4         List infixArray = getInfixArray(expression);
5         System.out.println(infixArray);

结果

[1, +, (, (, 2, +, 3, ), *, 4, ), -, 5]

2、按照思路将中缀表达式转化为后缀表达式(这里为了方便,将结果栈s2定义为数组,不必进行弹出后再倒序)。同时,定义了一个判断符号优先级的方法。

 1     public static List infixToSuffix(List infix){
 2         //符号栈
 3         Stack s1 = new Stack();
 4         //结果,由于后期需要逆序得到结果,这里用数组
 5         List s2 = new ArrayList<>();
 6 
 7         for (String item : infix) {
 8             if(item.matches("\\d+")){
 9                 //如果是一个数字
10                 s2.add(item);
11             }else if(item.equals("(")){
12                 //左括号,入符号栈
13                 s1.push(item);
14             }else if(item.equals(")")){
15                 //右括号,直到找到左括号
16                 while (!s1.peek().equals("(")){
17                     s2.add(s1.pop());
18                 }
19                 s1.pop();//弹出左括号
20             }else {
21                 //不为空,且优先级小于等于栈顶的
22                 while (s1.size() != 0 && properties(item) <= properties(s1.peek())){
23                     s2.add(s1.pop());
24                 }
25                 //否则,直接入栈
26                 s1.push(item);
27             }
28         }
29 
30         //表达式遍历完成,s1出栈加入到s2
31         while (!s1.isEmpty()){
32             s2.add(s1.pop());
33         }
34         return s2;
35     }
36 
37     //计算符号的优先级
38     public static int properties(String oper){
39         int res = 0;
40         switch (oper){
41             case "+":
42                 res = 1;
43                 break;
44             case "-":
45                 res = 1;
46                 break;
47             case "*":
48                 res = 2;
49                 break;
50             case "/":
51                 res = 2;
52                 break;
53             default:
54                 System.out.println("运算符错误");
55                 break;
56         }
57         return res;
58     }

测试

1         //中缀转后缀
2         List suffix = infixToSuffix(infixArray);
3         System.out.println(suffix);
4         System.out.println();
5 
6         int res = calculate(suffix);
7         System.out.println(res);

结果

运算符错误
运算符错误
[1, 2, 3, +, 4, *, +, 5, -]

16

 

你可能感兴趣的:(10、栈-中缀表达式转后缀表达式)