from operator import add, sub, mul
def div(x, y):
# 使用整数除法的向零取整方式
return int(x / y) if x * y > 0 else -(abs(x) // abs(y))
class Solution(object):
op_map = {'+': add, '-': sub, '*': mul, '/': div}
def evalRPN(self, tokens: List[str]) -> int:
stack = []
for token in tokens:
if token not in {'+', '-', '*', '/'}:
stack.append(int(token))
else:
op2 = stack.pop()
op1 = stack.pop()
stack.append(self.op_map[token](op1, op2)) # 第一个出来的在运算符后面
return stack.pop()
这段代码实现了一个逆波兰式(Reverse Polish Notation, RPN)表达式求值的功能。下面对每部分进行详细解释:
-
导入操作符:
from operator import add, sub, mul
引入了
add
(加法)、sub
(减法)和mul
(乘法)这三个操作符。 -
定义了整数除法的自定义函数:
def div(x, y): return int(x / y) if x * y > 0 else -(abs(x) // abs(y))
这个函数用于处理除法运算,采用了向零取整的方式。它判断两个操作数
x
和y
的符号:- 如果同号,就使用普通的整除。
- 如果异号,就使用绝对值整除后取负,确保结果向零取整。
-
定义了
Solution
类:class Solution(object): op_map = {'+': add, '-': sub, '*': mul, '/': div}
这个类中包含一个字典
op_map
,用于将操作符字符串(如'+'
)映射到对应的操作符函数。 -
实现了
evalRPN
方法:def evalRPN(self, tokens: List[str]) -> int: stack = [] for token in tokens: if token not in {'+', '-', '*', '/'}: stack.append(int(token)) else: op2 = stack.pop() op1 = stack.pop() stack.append(self.op_map[token](op1, op2)) return stack.pop()
这个方法的功能是计算给定的逆波兰式表达式:
- 使用一个栈
stack
来存储操作数。 - 遍历输入的
tokens
列表,如果当前 token 是数字,则将其入栈;如果是运算符,则从栈中弹出两个操作数,进行运算,然后将结果再入栈。 - 最终返回栈顶元素,即结果。
- 使用一个栈
总的来说,这段代码通过使用栈结构实现了对逆波兰表达式的求值,其中支持加法、减法、乘法和自定义的向零取整除法。
在这段代码中,对于异号除法使用 -(abs(x) // abs(y))
是为了确保结果向零取整,即符合一般的数学约定。这里详细解释一下原因:
整数除法的特性
-
向下取整(使用
//
):- Python 的整数除法(
//
)会返回向下取整的结果。这意味着对于负数结果,得到的将是更小的整数(例如-2.3
会被向下取整为-3
)。
- Python 的整数除法(
-
向零取整:
- 向零取整的意思是:如果结果为负,取大于等于该小数的最大整数。
具体的处理
对于异号的情况:
- 例子:
7 / -3
计算:- 直接用整除实际上会得到:
int(7 / -3)
=int(-2.333...)
=-3
(向下取整)。 - 但我们希望得到:
-2
(向零取整)。
- 直接用整除实际上会得到:
为了达到这个目的,使用了 -(abs(x) // abs(y))
:
abs(x)
和abs(y)
确保了计算是以正数进行的。//
进行整除(向下取整),结果是2
。- 最后,取负号,得到
-2
,即向零取整。
总结
所以,针对异号的情况,使用 -(abs(x) // abs(y))
是为了确保结果向零取整,而不是向下取整,从而得到符合期望的整数结果。