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 }

浙公网安备 33010602011771号