逆波兰计算器(后缀计算器)
后缀表达式计算器思路:
中缀转后缀思路:
- 设置两个栈,运算符栈s1,辅助栈s2
- 从左到右遍历中缀表达式
- 遇到操作数,压入s2
- 遇到括号
- 如果是左括号,直接压入s1
- 如果是右括号,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为主,并丢弃这一对括号
- 遇到操作符
- 如果s1为空,直接压入s1
- 否则,若低于s1栈顶操作符的优先级,则弹出s1栈顶的运算符,并压入s2,然后再次将扫描处的操作符与s1栈顶元素的优先级比较,直到高于它(或者s1没有元素了),便停止。再将其压入s1栈
- 将s1中剩余的运算符依次弹出并压入s2
- 依次弹出s2的元素,再逆序,即是对应的后缀表达式
package 数据结构; import java.util.ArrayList; import java.util.List; import java.util.Stack; public class NiBoLanCalculator { //将字符串表达式放入ArrayList,方便遍历 //注意表达式中操作数与操作符之间必须有空格(包括“()”) public static List<String> toArrayList(String expression){ String[] split = expression.split(" "); List<String> list = new ArrayList<>(); for (String ele : split) { list.add(ele); } return list; } //将中缀转为后缀 public static List<String> midToEnd(List<String> list) { Stack<String> s1 = new Stack<>(); //由于s2实际上并没有pop操作,且还需将其逆序才是结果,因此可以直接用ArrayList替代。 ArrayList<String> s2 = new ArrayList<>() ; int sign = 0; for (String ele : list) { if (ele.matches("\\d+")) { s2.add(ele); } else if (ele.equals("(") || ele.equals(")")) { if (ele.equals("(")) { s1.push(ele); } else { while (!s1.peek().equals("(")) { s2.add(s1.pop()); } s1.pop();//!!! } } else if (ele.equals("+") || ele.equals("-") || ele.equals("*") || ele.equals("/")) { while (!s1.isEmpty() && priority(ele) <= priority(s1.peek())){ s2.add(s1.pop()); } s1.push(ele); } } while (!s1.isEmpty()){ s2.add(s1.pop()); } return s2; } //进行计算 public static int calculate(List<String> list){ Stack<String> stack = new Stack<>(); //从左往右扫描表达式,若是操作数直接入栈,遇到操作符则取出栈顶前两个元素进行运算,计算结果重新压入栈顶 for(String ele: list){ if (ele.matches("\\d+")){ //匹配一个不限于一位的数 stack.push(ele); }else{ int num2 = Integer.parseInt(stack.pop()); int num1 = Integer.parseInt(stack.pop()); int res = 0; if (ele.equals("+")){ res = num1 + num2; }else if (ele.equals("-")){ res = num1 - num2; }else if (ele.equals("*")){ res = num1 * num2; }else if (ele.equals("/")){ res = num1 / num2; }else throw new RuntimeException("运算符有误"); stack.push(res + ""); } } return Integer.parseInt(stack.pop()); } //判断优先级 public static int priority(String c){ return switch (c) { case "+", "-" -> 1; case "*", "/" -> 2; default -> -1; }; } }
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决