有人可以为我解释这个递归吗?

时间:2016-03-07 06:51:56

标签: python recursion python-2.x

我从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])

真的很难理解。

BTW,此代码仅适用于Python 2.7。如果要在Python 3上进行测试,则应更改

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

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

3 个答案:

答案 0 :(得分:4)

递归函数用于计算数字的幂(最可能是整数,非负数或-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)只是意味着您希望通过对有力数字0 -1或x)提升到其中的一半>

(最有可能通过减少所需的乘法次数来加速计算 - 想象一下如果你有计算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

下一个是你得到两个分开的力量的模数。这是为了解决奇数的情况(即,当幂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个案例)并且相当于三元表达式:< / p>

1 if n % 2 == 0 else x

答案 1 :(得分:0)

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

假设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])

答案 2 :(得分:0)

正确的答案可能在下面

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])