计算逆波兰表达式

⭐作者介绍:大二本科网络工程专业在读,持续学习Java,努力输出优质文章
⭐作者主页:@逐梦苍穹
⭐所属专栏:数据结构。数据结构专栏主要是在讲解原理的基础上拿Java实现
⭐码云地址超链接(Gitee):这里存放我学习数据结构过程的全部代码

目录

  • 1、计算步骤
  • 2、具体操作
  • 3、代码实现
    • 3.1、得到逆波兰表达式
    • 3.2、存入list
    • 3.3、开始计算

计算逆波兰表达式_第1张图片

⭐如果不太了解三种数学表达式,可以查看我这篇文章:前缀表达式、中缀表达式、后缀表达式

1、计算步骤

逆波兰表达式(Reverse Polish Notation,RPN)是一种用于表示和计算数学表达式的方法,它通过使用后缀表示法而不是传统的中缀表示法。计算逆波兰表达式的步骤如下:

  1. 创建一个空的栈,用于存储操作数和中间结果。

  2. 从左到右扫描逆波兰表达式的每个元素。

  3. 如果当前元素是一个操作数(即数字),将其压入栈中。

  4. 如果当前元素是一个操作符(如加法、减法、乘法、除法等),则从栈中弹出两个操作数。

  5. 对弹出的两个操作数执行相应的操作,并将结果压入栈中。

  6. 重复步骤 3-5,直到扫描完整个逆波兰表达式。

当扫描结束后,栈中只剩下一个元素,即为最终的计算结果。

2、具体操作

计算表达式 “123+4*+5-” 的逆波兰表达式:

  1. 创建一个空栈。
  2. 从左到右扫描表达式的每个元素。
    ○ 遇到 1,将其压入栈中。
    ○ 遇到 2,将其压入栈中。
    ○ 遇到 3,将其压入栈中。
    ○ 遇到 + 操作符,从栈中弹出 3 和 2,执行加法操作得到 5,并将结果 5 压入栈中。
    ○ 遇到 4,将其压入栈中。
    ○ 遇到 * 操作符,从栈中弹出 4 和 5,执行乘法操作得到 20,并将结果 20 压入栈中。
    ○ 遇到 + 操作符,从栈中弹出 20 和 1,执行加法操作得到 21,并将结果 21 压入栈中。
    ○ 遇到 5,将其压入栈中。
    ○ 遇到 - 操作符,从栈中弹出 5 和 21,执行减法操作得到 16,并将结果 16 压入栈中。
  3. 扫描完整个表达式后,栈中只剩下一个元素 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());
    }

}

你可能感兴趣的:(数据结构,java,算法,数据结构)