⭐作者介绍:大二本科网络工程专业在读,持续学习Java,努力输出优质文章
⭐作者主页:@逐梦苍穹
⭐所属专栏:数据结构。数据结构专栏主要是在讲解原理的基础上拿Java实现
⭐码云地址超链接(Gitee):这里存放我学习数据结构过程的全部代码
目录
- 1、计算步骤
- 2、具体操作
- 3、代码实现
- 3.1、得到逆波兰表达式
- 3.2、存入list
- 3.3、开始计算
⭐如果不太了解三种数学表达式,可以查看我这篇文章:前缀表达式、中缀表达式、后缀表达式
1、计算步骤
逆波兰表达式(Reverse Polish Notation,RPN)是一种用于表示和计算数学表达式的方法,它通过使用后缀表示法而不是传统的中缀表示法。计算逆波兰表达式的步骤如下:
-
创建一个空的栈,用于存储操作数和中间结果。
-
从左到右扫描逆波兰表达式的每个元素。
-
如果当前元素是一个操作数(即数字),将其压入栈中。
-
如果当前元素是一个操作符(如加法、减法、乘法、除法等),则从栈中弹出两个操作数。
-
对弹出的两个操作数执行相应的操作,并将结果压入栈中。
-
重复步骤 3-5,直到扫描完整个逆波兰表达式。
当扫描结束后,栈中只剩下一个元素,即为最终的计算结果。
2、具体操作
计算表达式 “123+4*+5-” 的逆波兰表达式:
- 创建一个空栈。
- 从左到右扫描表达式的每个元素。
○ 遇到 1,将其压入栈中。
○ 遇到 2,将其压入栈中。
○ 遇到 3,将其压入栈中。
○ 遇到 + 操作符,从栈中弹出 3 和 2,执行加法操作得到 5,并将结果 5 压入栈中。
○ 遇到 4,将其压入栈中。
○ 遇到 * 操作符,从栈中弹出 4 和 5,执行乘法操作得到 20,并将结果 20 压入栈中。
○ 遇到 + 操作符,从栈中弹出 20 和 1,执行加法操作得到 21,并将结果 21 压入栈中。
○ 遇到 5,将其压入栈中。
○ 遇到 - 操作符,从栈中弹出 5 和 21,执行减法操作得到 16,并将结果 16 压入栈中。 - 扫描完整个表达式后,栈中只剩下一个元素 16,即为最终的计算结果。
3、代码实现
3.1、得到逆波兰表达式
这部分请查看我另外一篇文章:中缀表达式转后缀表达式
3.2、存入list
public static String postfixExpressionToList(Stack<Object> IntermediateResultStack) {
Object[] postfixExpression = new Object[IntermediateResultStack.getMaxSize()];
List<Object> list = new ArrayList();
StringBuilder PostfixExpression_resultBuilder = new StringBuilder();
for (int i = 0; i < IntermediateResultStack.getMaxSize(); i++) {
if (IntermediateResultStack.getTop() != -1) {
postfixExpression[i] = IntermediateResultStack.pop();
}
}
for (int i = postfixExpression.length - 1; i >= 0; i--) {
if (postfixExpression[i] != null) {
PostfixExpression_resultBuilder.append(postfixExpression[i]);
list.add(postfixExpression[i]);
}
}
System.out.println(list);
return PostfixExpression_resultBuilder.toString();
}
3.3、开始计算
package stack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author 逐梦苍穹
* @date 2023/6/23 10:03
*/
public class CountPostfixExpression {
public static void main(String[] args) {
String PostfixExpression = "123+4*+5-";
//[1, 2, 3, +, 4, *, +, 5, -]
List<String> list = new ArrayList<>(Arrays.asList("1", "2", "3", "+", "4", "*", "+", "5", "-"));
int calculate = calculate(list);
System.out.println("PostfixExpression(" + PostfixExpression + ") = " + calculate);
}
//完成对逆波兰表达式的运算
/*
* 1)从左至右扫描,将1和2和3压入堆栈;
2)遇到+运算符,因此弹出3和2(3为栈顶元素,2为次顶元素),计算出3+2的值,得5,再将5入栈;(此时栈内的元素:154*+5-)
3)将5入栈;
4)遇到4,把4入栈
5)接下来是×运算符,因此弹出4和5,计算出5 * 4=20,将20入栈;
6)遇到+,弹出1和20,计算1+20=21,入栈
7)遇到5,将5入栈;
8)最后是-运算符,计算出21-5的值,即16,由此得出最终结果
*/
public static int calculate(List<String> ls) {
// 创建给栈, 只需要一个栈即可
Stack<String> stack = new Stack<String>(15);
// 遍历 ls
for (String item : ls) {
// 这里使用正则表达式来取出数
if (item.matches("\\d+")) { // 匹配的是多位数
// 入栈
stack.push(item);
} else {
// pop出两个数,并运算, 再入栈
int num2 = Integer.parseInt((String) stack.pop());
int num1 = Integer.parseInt((String) stack.pop());
int res = 0;
if (item.equals("+")) {
res = num1 + num2;
} else if (item.equals("-")) {
res = num1 - num2;
} else if (item.equals("*")) {
res = num1 * num2;
} else if (item.equals("/")) {
res = num1 / num2;
} else {
throw new RuntimeException("运算符有误");
}
//把res 入栈
stack.push("" + res);
}
}
//最后留在stack中的数据是运算结果
return Integer.parseInt((String) stack.pop());
}
}