首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >栈的学习——逆波兰表达式(RPN)

栈的学习——逆波兰表达式(RPN)

作者头像
Han.miracle
发布2025-12-22 14:11:04
发布2025-12-22 14:11:04
1990
举报

逆波兰表达式

地址:https://leetcode.cn/problems/evaluate-reverse-polish-notation/ 为了让打大家好理解一点,博主这里选择与普通算式做一个对比,来方便大家理解。 逆波兰表达式 前缀表达式(Polish Notation, PN):运算符写在操作数前面。 例:中缀 3 + 4 → 前缀 + 3 4

后缀表达式(Reverse Polish Notation, RPN):运算符写在操作数后面。 例:中缀 3 + 4 → 后缀 3 4 +

中缀表达式:运算符写在两个操作数中间。 例:3 + 4

👉 名字来源:最早由波兰逻辑学家 卢卡西维茨 (Lukasiewicz) 提出,波兰表示法是前缀运算(+ 3 4),逆波兰就是后缀(3 4 +)。 2️⃣ 三种表达式对照示例 示例 1

中缀:3 + 4 * 5

前缀:+ 3 * 4 5

后缀:3 4 5 * +

示例 2

中缀:(a + b) * (c - d)

前缀:* + a b - c d

后缀:a b + c d - *

示例 3

中缀:a + b * c - d / e

前缀:- + a * b c / d e

后缀:a b c * + d e / -

在这里插入图片描述
在这里插入图片描述

选择题快速计算方法

后缀表达式:

  • 你根据加减乘除的算法顺序,在每一个要计算的表达式加上括号 -
在这里插入图片描述
在这里插入图片描述
  • 然后你把这个每一个括号里的运算符往后一个要计算的运算括号外的右边移动
在这里插入图片描述
在这里插入图片描述
  • 最后,把括号去掉就是中缀表达式转换为后缀表达式
在这里插入图片描述
在这里插入图片描述

前缀表达式:

  • 你根据加减乘除的算法顺序,在每一个要计算的表达式加上括号
在这里插入图片描述
在这里插入图片描述
  • 然后你把这个每一个括号里的运算符往前一个要计算的运算括号里移动到左边去,比如-b 这个运算括号区域内是最外侧,所以把这个-号移动到最外侧的括号的外边,也就是现在第一个的字符
在这里插入图片描述
在这里插入图片描述
  • 最后,把括号去掉就是中缀表达式转换为前缀表达式

从代码层面解决这个问题

思路讲解

  • 用一个栈保存“尚未参与计算的操作数”。
  • 从左到右遍历 tokens:
    • 遇到数字:压栈(先不算)。 -遇到运算符: -先 pop 出右操作数 p1,再 pop 出左操作数 p2; -计算 p2 op p1; -把结果转成字符串压回栈。
  • 遍历结束后,栈中只剩最后一个字符串数字,把它 parseInt 返回。
  • 关键:RPN 的“谁先算”由位置决定,不用括号;出栈顺序固定保证了非交换运算(减、除)的方向正确。

1.判断是否是运算符 2.判断完完后,如果是运算符,我们取栈里顶部的数字,根据不同的运算符进行计算,然后在把这个进行完计算的数,把这个获取的数重新压入栈中。 3.如果不是运算符的话,说明是数字,我们直接压入栈中,等待计算即可 4.循环下去,我们就可以得到最后一个结果,最后留下来的就是计算的结果 这个方法是用的字符串的,这个是我第一次做出来思路,不过给复杂化了,思路没有问题

代码语言:javascript
复制
//这个方法是用的字符串的,这个是我第一次做出来思路,不过给复杂化了,思路没有问题
class Solution {
    public int evalRPN(String[] tokens) {
        Stack<String> stack = new Stack<>();
        //首先创建一个栈
        for(String x : tokens) {
if(isOperator(x)){
    //true 说明是运算符
    //注意:先弹出的是要放发到右运算位的
    
    Integer p1 = Integer.valueOf(stack.pop());//右操作数
    Integer p2 = Integer.valueOf(stack.pop());//左操作数
    //切记先出栈的要放到右运算位
    Integer p3 = 0;
    switch (x) {
        case "+":
      p3 = p2+p1;
       break;
       case  "-":
       p3 =p2 - p1;
       break;
       case "*":
        p3 =p2 * p1;
       break;
       case "/" :
       p3 =p2 / p1;
       break;
    }
    stack.push(String.valueOf(p3));
    }else {
        //如果说是数字
        stack.push(x);
    }

}
        return Integer.parseInt(stack.pop());
       
    }
    public boolean isOperator(String x) {
        if(x.equals("+" ) || x.equals ("-") || x.equals("/")  || x.equals( "*")){
            return true;
        }
        return false;
    }
}

接下来我给大家在来一个 用Integer 的方法,刚刚那个方法一直在来回转换,博主没有转过这个弯,希望对大家有所帮助。

代码语言:javascript
复制
for (String x : tokens) {
    if (isOperator(x)) {
        Integer p1 = Integer.valueOf(stack.pop()); // 右操作数
        Integer p2 = Integer.valueOf(stack.pop()); // 左操作数
        Integer p3 = 0;
        switch (x) {
            case "+": p3 = p2 + p1; break;
            case "-": p3 = p2 - p1; break; // 左 - 右
            case "*": p3 = p2 * p1; break;
            case "/": p3 = p2 / p1; break; // 左 / 右(int 向0取整)
        }
        stack.push(String.valueOf(p3));
    } else {
        stack.push(x); // 数字先存着
    }
}
return Integer.parseInt(stack.pop());

//方法:判断是不是运算符
public boolean isOperator(String x) {
    return x.equals("+") || x.equals("-") || x.equals("/") || x.equals("*");
}

1.同样是判断是否是运算符 2.判断完完后,如果是运算符,我们取栈里顶部的数字,根据不同的运算符进行计算,然后在把这个进行完计算的数,把这个获取的数重新压入栈中。 3.如果不是运算符的话,说明是数字,我们直接压入栈中,等待计算即可 4.循环下去,我们就可以得到最后一个结果,最后留下来的就是计算的结果

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 逆波兰表达式
  • 选择题快速计算方法
  • 从代码层面解决这个问题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档