思路步骤分析:
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 }标签:11,中缀,int,s2,s1,ret,运算符,lists,表达式 From: https://www.cnblogs.com/yumengqifei/p/16567764.html