2025-01-14 完整逆波兰计算器实现

This commit is contained in:
liangjinglin 2025-01-14 16:51:22 +08:00
parent 30cfd63a65
commit dece7fcaa0
2 changed files with 119 additions and 9 deletions

View File

@ -50,7 +50,7 @@ public class ArrayStack<E> {
return top == -1;
}
public void push(int data){
public void push(Object data){
if(isFull()){
System.out.println("栈满,无法加入新数据");
return;

View File

@ -1,25 +1,33 @@
package stack;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
import java.util.*;
import java.util.regex.Pattern;
public class ReversePoland {
private ArrayStack<Integer> numStack = new ArrayStack(10);
private ArrayStack<String> operStack = new ArrayStack(20);
private ArrayStack<String> tempStack = new ArrayStack(20);
private List<String> expressList = new ArrayList<>();
/**
* 逆波兰表达式计算
* @param expression
* @return
*/
public int calculate(String expression){
translateExpress(expression);
int length = expressList.size();
String operRegex = "[+\\-*/]";
Pattern operPattern = Pattern.compile(operRegex);
//从左往右开始扫描
for (int i = 0; i<length;i++){
String str = expressList.get(i);
if (operPattern.matcher(str).matches()) {
// 如果是运算符从数栈中弹出两个数进行运算将结果入栈
if("+".equals(str)){
int num1 = numStack.pop();
int num2 = numStack.pop();
@ -45,17 +53,119 @@ public class ReversePoland {
numStack.push(result);
}
} else {
// 如果是数字直接入栈
numStack.push(Integer.parseInt(expressList.get(i)));
}
}
// 当扫描到最后一个时就是结果直接弹出
return numStack.pop();
}
/**
* 中缀表达式转逆波兰表达式
* @param expression
*/
public void translateExpress(String expression){
String[] strArr = expression.split(";");
for (String str : strArr){
expressList.add(str);
int length = expression.length();
String numStr = "";
// 正则表达式匹配单个数字
String regex = "\\d";
// 创建一个Pattern对象
Pattern pattern = Pattern.compile(regex);
// 从左到右遍历
for(int i =0; i < length; i++){
String str = expression.substring(i,i+1);
// 如果是数字直接入暂存栈
if (pattern.matcher(str).matches()) {
numStr += str;
if (i == length - 1){
tempStack.push(numStr);
continue;
}
// 如果不是最后一位需要判断是否为多位数根据下一个字符是否为符号如果是符号则生成当前数字
String nextStr = expression.substring(i+1,i+2);
if (!pattern.matcher(nextStr).matches()){
tempStack.push(numStr);
numStr = "";
}
}else {
// 如果是符号
if (operStack.isEmpty()){
// 如果符号栈为空则直接入栈
operStack.push(str);
continue;
}
if ("(".equals(str)){
// 如果当前符号是左括号则直接入符号栈
operStack.push(str);
continue;
}
if (")".equals(str)){
// 如果当前符号是右括号
while (true) {
// 如果符号栈顶是左括号则将左括号弹出结束循环
if ("(".equals(operStack.top())){
operStack.pop();
break;
}
// 如果符号栈顶不是左括号则将当前符号栈顶元素弹出直至碰到左括号
tempStack.push(operStack.pop());
}
continue;
}
while (true) {
// 如果当前符号为运算符
if (operStack.isEmpty()){
// 如果符号栈为空则直接入栈
operStack.push(str);
break;
}
if ("(".equals(operStack.top())){
// 如果符号栈顶是左括号则直接入符号栈
operStack.push(str);
break;
}
if (priority(str) > priority(operStack.top())){
// 如果当前符号优先级大于符号栈顶则直接入符号栈
operStack.push(str);
break;
} else {
// 如果都不符合以上条件则将符号栈顶元素弹出直至符合上述3个条件其中一个为止
String topStr = operStack.pop();
tempStack.push(topStr);
}
}
}
}
//将运算符栈中的数据全部弹出到临时栈中
while (true) {
if (operStack.isEmpty()){
break;
}
String topStr = operStack.pop();
tempStack.push(topStr);
}
reverse();
}
public int priority(String oper){
if ("+".equals(oper) || "-".equals(oper)){
return 0;
}
return 1;
}
public void reverse(){
while (true) {
if (tempStack.isEmpty()){
break;
}
expressList.add(tempStack.pop());
}
Collections.reverse(expressList);
System.out.println("逆波兰表达式为:");
for (String str : expressList){
System.out.print(str + ";");
}
}