【问题标题】:Can someone explain this recursive for me?有人可以为我解释这个递归吗?
【发布时间】:2016-03-07 06:51:55
【问题描述】:

我从 leetcode 得到这个代码。

class Solution(object):
    def myPow(self, x, n):
         if n == 0: 
             return 1
         if n == -1: 
             return 1 / x
         return self.myPow(x * x, n / 2) * ([1, x][n % 2])

这段代码用于实现poe(x, n),在Python中表示x**n

我想知道为什么它可以实现pow(x, n)

看起来没有意义……

我明白了

if n == 0: 
and
if n == -1:

但核心代码:

self.myPow(x * x, n / 2) * ([1, x][n % 2])

真的很难理解。

顺便说一句,此代码仅适用于 Python 2.7。如果你想在 Python 3 上测试,你应该改变

myPow(x*x, n / 2) * ([1, x][n % 2])

myPow(x*x, n // 2) * ([1, x][n % 2]) 

【问题讨论】:

  • @AnttiHaapala 它被标记为python-2.x。但是,是的,值得一提。
  • *虽然这被标记为 Python 2,因为它假定 / 是地板分区;将/ 替换为//,它可以在任何地方使用。
  • 为什么需要上课?为什么不只是def myPow(x, n)
  • [1, x][n % 2] 可以更清晰地表达为x if n % 2 else 1

标签: python recursion python-2.x


【解决方案1】:

递归函数是计算一个数字的幂(很可能是整数,非负数或-1,幂),正如您所期望的那样(类似于x = 2.2n = 9 )。

(这似乎是为Python 2.x 编写的(由于n/2 的预期结果是integer 而不是n//2))

最初的returns 是非常简单的数学运算。

 if n == 0: 
     return 1
 if n == -1: 
     return 1 / x

当幂为0,则返回1,然后幂为-1,则返回1/x

现在下一行包含两个元素:

self.myPow(x * x, n/2)
and
[1, x][n%2]

第一个self.myPow(x * x, n/2) 只是意味着你想通过平方幂数x 将更高的功率(不是0-1)变成一半

(很可能通过减少所需的乘法次数来加快计算速度 - 想象一下,如果你有计算 2^58 的情况。通过乘法,你必须将数字乘以 58 次。但如果你每次将其一分为二并递归求解,最终会减少操作数)。

例子:

x^8 = (x^2)^4 = y^4 #thus you reduce the number of operation you need to perform

在这里,您将x^2 作为递归中的下一个参数(即y)并递归执行,直到幂为0-1

下一个是你得到两个除法的模数。这是为了弥补 odd 的情况(即当幂 n 为奇数时)。

[1,x][n%2] #is 1 when n is even, is x when n is odd

如果nodd,那么通过执行n/2,你会在这个过程中失去一个x。因此,您必须通过将self.myPow(x * x, n / 2)x 相乘来弥补。但是如果你的n 不是奇数(偶数),你不会失去一个x,因此你不需要将结果乘以x,而是乘以1

举例说明:

x^9 = (x^2)^4 * x #take a look the x here

但是

x^8 = (x^2)^4 * 1 #take a look the 1 here

因此,这个:

[1, x][n % 2]

是将前面的递归乘以1(偶数n)或x(奇数n),相当于三元表达式:

1 if n % 2 == 0 else x

【讨论】:

  • 感谢您的解释!非常清晰!但是为什么这段代码要使用 (x^2)^4 而不是 x^8 呢? x^8 似乎更清晰了!
  • @MarsLee 我猜,它可能会通过减少 * 来加快计算过程,让我们说非常大的 n(想象 2^50 案例)
  • 抱歉,我还有一个问题。那么如果 n 为负数,会发生什么?
  • 会这样工作吗? x^-9 = (x^2)^-5 * x
  • 我已经在 python 3.5.1 中尝试过:-9/2 == -4.5 所以这可能只适用于 python 2.7
【解决方案2】:

这是分而治之的技术。上面的实现是一种计算幂的快速方法。在每次调用时,都会消除一半的乘法。

假设n是偶数,x^n可以写成如下(如果n是奇数,则需要多乘一次)

x^n = (x^2)^(n/2)
or
x^n = (x^n/2)^2

上面显示的函数实现了第一个版本。实现第二个也很容易(我在下面删除了递归基本案例)

r = self.myPow(x,n/2)
return r * r * ([1, x][n % 2])

【讨论】:

    【解决方案3】:

    正确答案可能在下面

    class Solution:
        def myPow(self, x: float, n: int) -> float:
    
            if n == 0: 
                return 1
            if n > 0:
                return self.myPow(x * x, int(n / 2)) * ([1, x][n % 2])
            else:
                return self.myPow(x * x, int(n / 2)) * ([1, 1/x][n % 2])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-13
      • 1970-01-01
      • 1970-01-01
      • 2018-03-19
      • 2018-07-23
      • 1970-01-01
      • 1970-01-01
      • 2021-12-24
      相关资源
      最近更新 更多