11--中缀表达式转后缀表达式

思路步骤分析:

1、初始化两个栈,运算符栈s1和储存中间结果的栈s2

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

3、遇到操作数时,将其压入s2

4、遇到运算符时,比较其与s1z栈顶运算符的优先级:

4.1:如果s1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈

4.2:否则,若优先级比栈顶运算符高,也将运算符压入s1

4.3:否则,将s1栈顶的运算符弹出并压入到s2中,再次转到(4.1)与新的栈顶运算符比较;

5、遇到括号时:

5.1:遇到左括号"(",则直接压入s1

5.2:如果是右括号")",则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃

6、重复步骤2至5,直到表达式的最右边

7、将s1中剩余的运算符依次弹出并压入s2

8、依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式

中缀表达式1+((2+3)*4)-5,图形过程:

 1 //新定义一个类【工具类】,用于比较运算符优先级
 2 class Operator{
 3     public static final int  ADD = 1;
 4     public static final int  SUB = 1;
 5     public static final int  MUL = 2;
 6     public static final int  DIV = 2;
 7     
 8     public static int priority(String item) {
 9         int ret = 0;
10         switch(item) {
11         case "+":
12             ret = ADD;
13             break;
14         case "-":
15             ret = SUB;
16             break;
17         case "*":
18             ret = MUL;
19             break;
20         case "/":
21             ret = DIV;
22             break;
23         default:
24             break;
25         }
26         return ret;
27     }
28 }
  1 import java.util.ArrayList;
  2 import java.util.List;
  3 import java.util.Stack;
  4 
  5 //逆波兰表达式的计算
  6 public class NiPolandExpression {
  7 
  8     public static void main(String[] args) {
  9         String expression = "1+((2+3)*425)-15"; //2111
 10         List<String> list = toInfixListExpression(expression);
 11         System.out.println(list);
 12         
 13         List<String> lists =  parseSuffixExpression(list);
 14         System.out.println(lists);
 15         
 16         //1、将表达式转成ArrayList集合,后遍历,每遍历一个元素将压栈
 17         Stack<String> stack = new Stack<>();
 18         for(String ele: lists) {
 19             if (ele.matches("\\d+")) { //正则表达式:表示匹配一个或者多个整数
 20                 //是数字直接入栈
 21                 stack.push(ele);
 22             }else {
 23                 //到了这里说明是符号,需要pop出2个操作数
 24                 int num2 = Integer.parseInt(stack.pop());
 25                 int num1 = Integer.parseInt(stack.pop());
 26                 int ret = 0;
 27                 switch(ele) {
 28                 case "+": 
 29                     ret = num1 + num2;
 30                     break;
 31                 case "-":
 32                     ret = num1 - num2;
 33                     break;
 34                 case "*":
 35                     ret = num1 * num2;
 36                     break;
 37                 case "/":
 38                     ret = num1 / num2;
 39                     break;
 40                     }
 41                 //将计算结果压入栈中
 42                 stack.push(ret+"");
 43             }
 44         }
 45         int result = Integer.parseInt(stack.pop());
 46         System.out.println("最终结果为:" + result);
 47     }
 48     
 49     public static List<String> getList(String expression){
 50         List<String> lists = new ArrayList<>();
 51         String[] arrays = expression.split(" ");
 52         for(String ele:arrays) {
 53             lists.add(ele);
 54         }
 55         return lists;
 56      }
 57     
 58     //将中缀表达式转成List集合
 59     public static List<String> toInfixListExpression(String expression){
 60         List<String> lists = new ArrayList<>();
 61         int i = 0; //字符串每个字符的索引
 62         char ch = ' ';
 63         while(i < expression.length()) {
 64             ch = expression.charAt(i);
 65             if (ch < '0' || ch > '9') {
 66                 //说明为运算符,直接加入到lists集合中
 67                 lists.add(ch+"");
 68                 i++;
 69             }else {
 70                 //说明改字符为数字
 71                 String str = "";
 72                 while(i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
 73                     str += expression.charAt(i++);
 74                 }
 75                 lists.add(str);
 76             }
 77         }
 78         return lists;
 79     }
 80     
 81     //中缀表达式转后缀表达式
 82     public static List<String> parseSuffixExpression(List<String> lists){
 83         //定义运算符栈
 84         Stack<String> s1 = new Stack<>();
 85         //定义存储中间结果的栈s2 【由于在转换过程中s2只添加数据,因此可以使用集合】
 86         //Stack<String> s2 = new Stack<>();
 87         List<String> s2 = new ArrayList<>();
 88         //扫描中缀表达式【集合】
 89         for(String item : lists){
 90             //如果是操作数,直接加入到s2中
 91             if (item.matches("\\d+")) {
 92                 s2.add(item);
 93             }else if ("(".equals(item)) {
 94                 //如果是左括号,直接压入s1
 95                 s1.push(item);
 96             }else if(")".equals(item)){
 97                 //依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,将这对括号丢弃
 98                 while(!"(".equals(s1.peek())) {
 99                     s2.add(s1.pop());
100                 }
101                 //弹出s1中的左括号
102                 s1.pop();
103             }else {
104                 //遇到运算符
105                 //当item的优先级小于或者等于s1栈顶的优先级时,则依次将s1栈顶的运算符pop到s2中,再次与s1新的栈顶的运算符相比较
106                 //直到当前运算符的优先级大于s1栈顶运算符的优先级
107                 //注:如果s2.peek为"("则返回0,会直接跳出循环
108                 while(s1.size() != 0 && Operator.priority(item) <= Operator.priority(s1.peek())) {
109                     s2.add(s1.pop());
110                 }
111                 //到达此处说明有3种【直接入栈s1】情况:
112                   //1、item运算符的优先级大于s1栈顶运算符的优先级
113                   //2、s1为空
114                   //3、s1栈顶为左括号
115                 s1.push(item);
116             }
117         }
118         //将s1中剩余的运算符弹出并加入到s2中
119         while(s1.size() != 0) {
120             s2.add(s1.pop());
121         }
122         return s2;
123     }
124     
125 }

posted @ 2022-09-06 09:00  羽梦齐飞  阅读(101)  评论(0)    收藏  举报