完整代码实例-Java实现简单的逆波兰计算器
完整代码示例如下:
package DataStrcture.StackDemo;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class PolanExpCaculator_copy {
/**
* 1.给定一个后缀表达式
* 2.我们把后缀表达式通过 split分割字符, 赋值给String数组,
* 3.遍历string数组, 把表达式的值一个个存储到集合中
* 4.遍历集合, 遇到数字就入栈,遇到操作符就从栈中pop两个数进行运算,然后存入栈中,
* 5.如此反复,栈中的唯一数就是表达式的结果了
*/
public static void main(String[] args) {
// (30+2)x5-6
String suffixExp = "30 2 + 5 x 6 -";
String infixExp = "( 30 + 2 ) x 5 - 6";
PolanExpCaculator_copy polan = new PolanExpCaculator_copy();
List<String> sufixList = polan.getList(suffixExp);
List<String> InfixList = polan.getList(infixExp);
System.out.println(sufixList);
System.out.println("===============");
int res = polan.calculate(sufixList);
System.out.println("表达式的运算结果为: " + res);
System.out.println("======================");
System.out.println("中缀表达式: " + infixExp + "转为后缀表达式为: ");
List<String> suffixExpression = polan.transferToSuffixExp(InfixList);
System.out.println(suffixExpression);
System.out.println("===============================");
int res_1 = polan.calculate(suffixExpression);
System.out.println("前缀表达式转为后缀表达式后的计算结果为: "+res_1);
}
//存储表达式到集合, 方便遍历表达式噢!
public List<String> getList(String exp) {
String[] expArry = exp.split(" ");
///新建集合对象
List<String> list = new ArrayList<String>();
for (String x : expArry) {
list.add(x);
}
return list;
}
//开始计算
public int calculate(List<String> list) {
//存储运算结果
int res = 0;
///栈,存储
Stack<String> numStack = new Stack<String>();
//循环list,取出元素
for (String item : list) {
//遇到数字入栈, 遇到操作符出栈
if (item.matches("\\d+")) {
numStack.push(item);
} else {
//遇到操作符,出栈做运算
/**
* 在这下面我们应用了String-->int的方法
* 法1. int x = Integer.parseInt(str);
* 法2. 间接法: String-->Integer-->int
* Integer integer = new Integer(str);
* integer.intValue();
*/
int num_2 = Integer.parseInt(numStack.pop());
int num_1 = Integer.parseInt(numStack.pop());
if (item.equals("+")) {
res = num_1 + num_2;
} else if (item.equals("-")) {
res = num_1 - num_2;
} else if (item.equals("x")) {
res = num_1 * num_2;
} else if (item.equals("/")) {
res = num_1 / num_2;
} else {
throw new RuntimeException("操作符有误! ");
}
String res_str = "" + res; //每次计算完成一次都要把结果重新入栈,供下次别的计算
numStack.push(res_str);
}
}
int real_res = Integer.parseInt(numStack.pop());
return real_res;
}
//规定运算符的优先级
public static int getPrioity(String op) {
if (op.equals("x") || op.equals("\\"))
return 0;
if (op.equals("+") || op.equals("-"))
return -1;
return 1;
}
///中缀表达式转后缀表达式
public List<String> transferToSuffixExp(List<String> list) {
List<String> suffixExpList = new ArrayList<String>();// 存储后缀表达式的元素
Stack<String> opStack = new Stack<String>();//存储符号栈
//遍历集合
for (String item : list) {
if (item.matches("\\d+")) {//1. 数字的直接存到集合
suffixExpList.add(item);
} else if (item.equals("(")) {//2. 左括号直接压到栈中
opStack.push(item);
} else if (item.equals(")")) {
//3. 遇见右括号,嘛也不管直接不停的出栈直到遇到了左括号
while (!(opStack.peek().equals("("))) {
suffixExpList.add(opStack.pop());
}
opStack.pop();
// 4.遇到的都是正儿八经的操作符,比较优先级后再决定入栈时机
} else {
// // 待插入栈的优先级大于栈顶操作符的优先级()
// if (opStack.size() == 0 || (opStack.peek().equals("(") || getPrioity(item) > getPrioity(opStack.peek()))) {
// opStack.push(item);
// } else {
///待插入栈的优先级小于或者等于栈顶元素, 不停的出栈 (切记别忘了判空,更不要忘了忽略栈顶是括号的情况(是括号就直接入栈))
while (opStack.size() > 0 && getPrioity(opStack.peek()) >= getPrioity(item) && !(opStack.peek().equals("(") ))
suffixExpList.add(opStack.pop());
opStack.push(item);
// }
}
}
while (opStack.size() > 0)
suffixExpList.add(opStack.pop());
return suffixExpList;
}
}
运行结果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)