2025-01-14 完整逆波兰计算器实现
This commit is contained in:
parent
30cfd63a65
commit
dece7fcaa0
@ -50,7 +50,7 @@ public class ArrayStack<E> {
|
|||||||
return top == -1;
|
return top == -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void push(int data){
|
public void push(Object data){
|
||||||
if(isFull()){
|
if(isFull()){
|
||||||
System.out.println("栈满,无法加入新数据");
|
System.out.println("栈满,无法加入新数据");
|
||||||
return;
|
return;
|
||||||
|
@ -1,25 +1,33 @@
|
|||||||
package stack;
|
package stack;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Scanner;
|
|
||||||
import java.util.Stack;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class ReversePoland {
|
public class ReversePoland {
|
||||||
|
|
||||||
private ArrayStack<Integer> numStack = new ArrayStack(10);
|
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<>();
|
private List<String> expressList = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 逆波兰表达式计算
|
||||||
|
* @param expression
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public int calculate(String expression){
|
public int calculate(String expression){
|
||||||
translateExpress(expression);
|
translateExpress(expression);
|
||||||
int length = expressList.size();
|
int length = expressList.size();
|
||||||
String operRegex = "[+\\-*/]";
|
String operRegex = "[+\\-*/]";
|
||||||
Pattern operPattern = Pattern.compile(operRegex);
|
Pattern operPattern = Pattern.compile(operRegex);
|
||||||
|
//从左往右开始扫描
|
||||||
for (int i = 0; i<length;i++){
|
for (int i = 0; i<length;i++){
|
||||||
String str = expressList.get(i);
|
String str = expressList.get(i);
|
||||||
if (operPattern.matcher(str).matches()) {
|
if (operPattern.matcher(str).matches()) {
|
||||||
|
// 如果是运算符,从数栈中弹出两个数,进行运算,将结果入栈
|
||||||
if("+".equals(str)){
|
if("+".equals(str)){
|
||||||
int num1 = numStack.pop();
|
int num1 = numStack.pop();
|
||||||
int num2 = numStack.pop();
|
int num2 = numStack.pop();
|
||||||
@ -45,17 +53,119 @@ public class ReversePoland {
|
|||||||
numStack.push(result);
|
numStack.push(result);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// 如果是数字,直接入栈
|
||||||
numStack.push(Integer.parseInt(expressList.get(i)));
|
numStack.push(Integer.parseInt(expressList.get(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 当扫描到最后一个时,就是结果,直接弹出
|
||||||
return numStack.pop();
|
return numStack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中缀表达式转逆波兰表达式
|
||||||
|
* @param expression
|
||||||
|
*/
|
||||||
public void translateExpress(String expression){
|
public void translateExpress(String expression){
|
||||||
String[] strArr = expression.split(";");
|
int length = expression.length();
|
||||||
for (String str : strArr){
|
String numStr = "";
|
||||||
expressList.add(str);
|
// 正则表达式,匹配单个数字
|
||||||
|
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 + ";");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user