⭐作者介绍:大二本科网络工程专业在读,持续学习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);// 遍历 lsfor (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());}}