【Java数据结构】中缀表达式转后缀表达式,后缀表达式的计算(多位数)

中缀表达式转后缀表达式,后缀表达式的计算(多位数)

中缀表达式转后缀表达式思路

(1)初始化两个栈stack1与stack2,分别存储数和操作符

(2)从左到右扫描中缀表达式

(3)遇到数字时,直接将其压入stack1中

(4)遇到操作符时,先进性比较优先级,

如果优先级比栈顶元素的高,则直接入栈

如果优先级比栈顶元素的低,则将栈顶元素弹出压入数栈,再将操作符与栈顶重复比较,直到可以入栈

如果符号栈为空或者栈顶是左括号(,则直接入栈

如果操作符是右括号),则将操作符依次出栈放入数栈中,直到遇到左括号,二者直接丢弃

(5)扫描完成,将操作符栈stack2依次出栈并压入stack1中

后缀表达式计算器思路

(1)初始化一个栈

(2)遇到数字时,直接将数字压入栈

(3)遇到运算符时,将栈顶的两个数弹出,并且计算,将结果入栈

Java代码如下

复制代码
  1 import java.util.ArrayList;
  2 import java.util.Deque;
  3 import java.util.LinkedList;
  4 import java.util.List;
  5 
  6 public class Main {
  7     public static void main(String[] args) {
  8         String str ="11+(2*4)+3*(61-1)";//结果为11+8+180=199
  9         //将字符串转成list
 10         List<String> List = toInfixExpressionList(str);
 11         System.out.println(List);
 12         //中缀表达式转后缀表达式
 13         List<String> suffixList = prefixToSuffix(List);
 14         System.out.println(suffixList);
 15         //计算后缀表达式的结果
 16         System.out.println("后缀表达式的计算结果为:"+toCalculation(suffixList));
 17     }
 18 
 19     /**
 20      * 将表达式每一个部分转换成list
 21      * @param str 计算表达式
 22      * @return List
 23      */
 24     public static List<String> toInfixExpressionList(String str){
 25         List<String> list = new ArrayList<>(str.length());
 26         int i = 0;//用于遍历表达式的指针
 27         char c;//用于存储每一个遍历到的字符
 28         StringBuilder s;//用于多位数的拼接
 29         while (i<str.length()){
 30             c = str.charAt(i);
 31             //如果是非数字,直接加入到list
 32             if(c < 48 || c > 57){
 33                 list.add(""+c);
 34                 i++;
 35             }else {
 36                 s = new StringBuilder();
 37                 while (c >= 48 && c <= 57){
 38                     s.append(c);
 39                     i++;
 40                     c = str.charAt(i);
 41                 }
 42                 list.add(s.toString());
 43             }
 44         }
 45         return list;
 46     }
 47 
 48     /**
 49      * 计算后缀表达式
 50      * @return 计算结果
 51      */
 52     public static Integer toCalculation(List<String> list){
 53         Deque<String> stack = new LinkedList<>();
 54         for(String item: list){
 55             if(isNumeric(item)){
 56                 stack.push(item);
 57             }else {
 58                 int x = Integer.parseInt(stack.pop());
 59                 int y = Integer.parseInt(stack.pop());
 60                 switch (item){
 61                     case "+":
 62                         stack.push((y+x)+"");
 63                         break;
 64                     case "-":
 65                         stack.push((y-x)+"");
 66                         break;
 67                     case "*":
 68                         stack.push((y*x)+"");
 69                         break;
 70                     case "/":
 71                         stack.push((y/x)+"");
 72                         break;
 73                     default:
 74                         throw new RuntimeException("输入错误!");
 75                 }
 76             }
 77         }
 78         return Integer.parseInt(stack.pop());
 79     }
 80 
 81     /**
 82      * 中缀表达式转后缀表达式
 83      * @return List
 84      */
 85     public static List<String> prefixToSuffix(List<String> list){
 86         //初始化两个栈,stack1为数栈,stack2为操作符栈
 87         List<String> stack1 = new ArrayList<>();
 88         Deque<String> stack2 = new LinkedList<>();
 89         for(String item: list){
 90             if(isNumeric(item)){
 91                 //数字直接入栈
 92                 stack1.add(item);
 93             }else if(item.equals("(")) {
 94                 //左括号或者空直接入栈
 95                 stack2.push(item);
 96             }else if(item.equals(")")){
 97                 //右括号将符号栈中左括号前的所有符号入数栈
 98                 while (!stack2.peek().equals("(")){
 99                     stack1.add(stack2.pop());
100                 }
101                 stack2.pop();//清除括号
102             }else if(stack2.peek()==null||judgePriority(item)>judgePriority(stack2.peek())){
103                 //优先级比栈顶元素高,直接入栈
104                 stack2.push(item);
105             }else {
106                 //优先级比栈顶元素低或者相等,将栈顶优先级高的入数栈
107                 while (stack2.peek()!=null&&judgePriority(stack2.peek())<=judgePriority(item)){
108                     stack1.add(stack2.pop());
109                 }
110                 stack2.push(item);
111             }
112         }
113         while (stack2.peek()!=null){
114             stack1.add(stack2.pop());
115         }
116 
117         return stack1;
118     }
119 
120     /**
121      * 返回运算符优先级,加减为1,乘除为2
122      * @param str 运算符
123      * @return 优先级
124      */
125     public static int judgePriority(String str){
126         switch (str){
127             case "+":
128                 return 1;
129             case "-":
130                 return 1;
131             case "*":
132                 return 2;
133             case "/":
134                 return 2;
135             case "(":
136                 return 0;
137             case ")":
138                 return 0;
139             default:
140                 throw new RuntimeException("输入有误!"+str);
141         }
142     }
143 
144     /**
145      * 判断字符串是否是正整数
146      * @param str 字符串
147      * @return boolean
148      */
149     public static boolean isNumeric(String str){
150         for (int i = str.length();--i>=0;){
151             if (!Character.isDigit(str.charAt(i))){
152                 return false;
153             }
154         }
155         return true;
156     }
157 }
复制代码

 

posted @   枫叶藏在眼眸  阅读(521)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示