力扣刷题-栈-逆波兰表达式求值

150. 逆波兰表达式求值

根据 逆波兰表示法,求表达式的值。

有效的运算符包括 + , - , * , / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

示例 1:

输入: ["2", "1", "+", "3", " * "]

输出: 9

解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

示例 2:

输入: ["4", "13", "5", "/", "+"]

输出: 6

解释: 该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

逆波兰表达式:是一种后缀表达式,所谓后缀就是指运算符写在后面。

平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。

该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。

逆波兰表达式主要有以下两个优点:

  • 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
  • 适合用栈操作运算:遇到数字则入栈;遇到运算符则取出栈顶两个数字进行计算,并将结果压入栈中。

思路

参考:https://www.programmercarl.com/0150.逆波兰表达式求值.html

本题中每一个子表达式要得出一个结果,然后拿这个结果再进行运算,那么这岂不就是一个相邻字符串消除的过程,和1047.删除字符串中的所有相邻重复项中的对对碰游戏是不是就非常像了。

代码

python 复制代码
class Solution(object):
    def evalRPN(self, tokens):
        """
        :type tokens: List[str]
        :rtype: int
        """
        # 后缀表达式 求值
        stack = []
        for i in range(len(tokens)):
            # 如果是运算符法 则需要弹出栈顶部两个元素 进行计算
            if tokens[i]=='+' or tokens[i]=='-' or tokens[i]=='*' or tokens[i]=='/':
                num1 = stack[-1] # 栈顶元素 注意原本是字符
                stack.pop() # 删除栈顶元素
                num2 = stack[-1] # 栈顶元素 其实是最开始栈顶的倒数第二个元素
                stack.pop()
                if tokens[i]=='+':
                    result = num1 + num2 # 计算结果
                    stack.append(result) # 将结果添加至栈
                elif tokens[i]=='-':
                    result = num1 - num2 # 计算结果
                    stack.append(result) # 将结果添加至栈
                elif tokens[i]=='*':
                    result = num1 * num2 # 计算结果
                    stack.append(result) # 将结果添加至栈
                elif tokens[i]=='/':
                    result = num1 / num2 # 计算结果
                    stack.append(result) # 将结果添加至栈
            else: # 如果是数字
                stack.append(int(tokens[i])) # 记得int转为整型数字
        return stack[-1]

但上述代码是有问题的!!! 存在两个问题:

  • 第一个是:在遇到运算符的时候,需要退出栈顶两个元素,退出的第一个元素num1应该放在运算符右边,退出的第二个元素num2应该放在运算符左边,所以加法时候运算规则应该是:num2 + num1
  • 第二个是:在除法运算时候,需要注意python的具体情况。

python 的整数除法是向下取整,而不是向零取整。

python2 的除法 "/" 是整数除法, "-3 / 2 = -2" ;

python3 的地板除 "//" 是整数除法, "-3 // 2 = -2" ;

python3 的除法 "/" 是浮点除法, "-3 / 2 = -1.5" ;

而 C++/Java 中的整数除法是向零取整。

C++/Java 中 "-3 / 2 = -1" .
本题的题意(一般情况)都是要求向零取整的。(遇到python除法的时候就应该想到)

对 Python 的整数除法问题,可以用** int(num2 / float(num1)) **来做,即先用浮点数除法,然后取整。

无论如何,浮点数除法都会得到一个浮点数 ,比如 "-3 / 2.0 = 1.5" ;

此时再取整,就会得到整数部分,即 int(-1.5) = -1 。

参考链接:https://leetcode.cn/problems/evaluate-reverse-polish-notation/solutions/668342/xiang-jie-ni-bo-lan-biao-da-shi-fu-ben-t-sfl6/

所以修正之后的代码:

python 复制代码
class Solution(object):
    def evalRPN(self, tokens):
        """
        :type tokens: List[str]
        :rtype: int
        """
        # 后缀表达式 求值
        stack = []
        for i in range(len(tokens)):
            # 如果是运算符法 则需要弹出栈顶部两个元素 进行计算
            if tokens[i]=='+' or tokens[i]=='-' or tokens[i]=='*' or tokens[i]=='/':
                num1 = stack.pop() # 栈顶元素 
                num2 = stack.pop() # 栈顶元素 其实是最开始栈顶的倒数第二个元素
                if tokens[i]=='+':
                    result = num2 + num1 # 计算结果 注意第一个出来的在运算符后面
                    stack.append(result) # 将结果添加至栈
                elif tokens[i]=='-':
                    result = num2 - num1 # 计算结果
                    stack.append(result) # 将结果添加至栈
                elif tokens[i]=='*':
                    result = num2 * num1 # 计算结果
                    stack.append(result) # 将结果添加至栈
                elif tokens[i]=='/':
                    result = int(num2 / float(num1)) # 计算结果 注意!!
                    stack.append(result) # 将结果添加至栈
            else: # 如果是数字
                stack.append(int(tokens[i]))
        return stack.pop()

其他

我们习惯看到的表达式都是中缀表达式,因为符合我们的习惯,但是中缀表达式对于计算机来说就不是很友好了。

例如:4 + 13 / 5,这就是中缀表达式,计算机从左到右去扫描的话,扫到13,还要判断13后面是什么运算符,还要比较一下优先级,然后13还和后面的5做运算,做完运算之后,还要向前回退到 4 的位置,继续做加法,你说麻不麻烦!

那么将中缀表达式,转化为后缀表达式之后:["4", "13", "5", "/", "+"] ,就不一样了,计算机可以利用栈来顺序处理,不需要考虑优先级了。也不用回退了, 所以后缀表达式对计算机来说是非常友好的

相关推荐
GIS小天8 分钟前
AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年7月4日第128弹
人工智能·算法·机器学习·彩票
满分观察网友z25 分钟前
开发者的“右”眼:一个树问题如何拯救我的UI设计(199. 二叉树的右视图)
算法
阿蒙Amon28 分钟前
【Python小工具】使用 OpenCV 获取视频时长的详细指南
python·opencv·音视频
橘子编程1 小时前
Python-Word文档、PPT、PDF以及Pillow处理图像详解
开发语言·python
蓝婷儿2 小时前
Python 机器学习核心入门与实战进阶 Day 2 - KNN(K-近邻算法)分类实战与调参
python·机器学习·近邻算法
森焱森2 小时前
无人机三轴稳定化控制(1)____飞机的稳定控制逻辑
c语言·单片机·算法·无人机
循环过三天2 小时前
3-1 PID算法改进(积分部分)
笔记·stm32·单片机·学习·算法·pid
呆瑜nuage2 小时前
数据结构——堆
数据结构
蓝澈11212 小时前
弗洛伊德(Floyd)算法-各个顶点之间的最短路径问题
java·数据结构·动态规划
zl_dfq2 小时前
数据结构 之 【堆】(堆的概念及结构、大根堆的实现、向上调整法、向下调整法)(C语言实现)
数据结构