逆波兰计算器(后缀计算器)

后缀表达式计算器思路:

 

中缀转后缀思路:

  1. 设置两个栈,运算符栈s1,辅助栈s2
  2. 从左到右遍历中缀表达式
  3. 遇到操作数,压入s2
  4. 遇到括号
    1. 如果是左括号,直接压入s1
    2. 如果是右括号,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为主,并丢弃这一对括号
  5. 遇到操作符
    1. 如果s1为空,直接压入s1
    2. 否则,若低于s1栈顶操作符的优先级,则弹出s1栈顶的运算符,并压入s2,然后再次将扫描处的操作符与s1栈顶元素的优先级比较,直到高于它(或者s1没有元素了),便停止。再将其压入s1栈
  6. 将s1中剩余的运算符依次弹出并压入s2
  7. 依次弹出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;
};
}
}

 

posted @   Amazzzzing  阅读(357)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
点击右上角即可分享
微信分享提示