简体   繁体   English

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

[英]Can someone explain this recursive for me?

I get this code from leetcode. 我从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])

This code is used to implement poe(x, n) , which means x**n in Python. 该代码用于实现poe(x, n) ,在Python中表示x**n

I want to know why it can implement pow(x, n) . 我想知道为什么它可以实现pow(x, n)

It looks doesn't make sense... 看起来没有意义...

I understand 我明白

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

But the core code: 但是核心代码:

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

is really hard to understand. 真的很难理解。

BTW, this code only works on Python 2.7. 顺便说一句,此代码仅适用于Python 2.7。 If you want to test on Python 3, you should change 如果要在Python 3上进行测试,则应进行更改

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

to

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

The recursive function is to compute power (most probably integer , non negative or -1 , power) of a number, as you might have expected (something like x = 2.2 and n = 9 ). 递归函数是计算数字的幂(最可能是整数 ,非负或-1幂),这可能与您期望的一样( x = 2.2n = 9 )。

(And this seems to be written for Python 2.x (due to the n/2 having expected result of integer instead of n//2 )) (而且这似乎是为Python 2.x编写的(由于n/2预期结果为integer而不是n//2 ))

The initial returns are very straight-forward math. 初始returns是非常简单的数学。

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

When the power is 0 , then you return 1 and then the power is -1 , you return 1/x . 当幂为0 ,返回1 ,然后幂为-1 ,则返回1/x

Now the next line consists of two elements: 现在,下一行包含两个元素:

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

The first one self.myPow(x * x, n/2) simply means you want to make higher power (not 0 or -1 ) into half of it by squaring the powered number x 第一个self.myPow(x * x, n/2)只是意味着您想通过平方xx使更高的功率(不是0-1 )变成一半

(most probably to speed up the calculation by reducing the number of multiplication needed - imagine if you have case to compute 2^58 . By multiplication, you have to multiply the number 58 times. But if you divide it into two every time and solve it recursively, you end up will smaller number of operations). (最有可能通过减少所需的乘法次数来加快计算的速度-想象一下如果有大小写的情况下要计算2^58通过乘法,您必须将数字乘以58倍。但是,如果每次将其除以2并求解递归的话,您最终将获得较少的操作)。

Example: 例:

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

Here, you pass x^2 as your next argument in the recursive (that is y ) and do it recursively till the power is 0 or -1 . 在这里,您将x^2作为递归中的下一个参数传递(即y ),然后递归执行直到功率为0-1为止。

And the next one is you get the modulo of two of the divided power. 下一个是得到除以2的幂的模。 This is to make up the case for odd case (that is, when the power n is odd). 这是为了弥补奇数情况(即,当幂n为奇数时)的情况。

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

If n is odd , then by doing n/2 , you lose one x in the process. 如果nodd ,则通过执行n/2 ,您将在此过程中损失一个x Thus you have to make up by multiplying the self.myPow(x * x, n / 2) with that x . 因此,你必须通过相乘来弥补self.myPow(x * x, n / 2)x But if your n is not odd (even), you do not lose one x , thus you do not need to multiply the result by x but by 1 . 但是,如果您的n不为奇数(偶数),则您不会损失x ,因此您无需将结果乘以x而是乘以1

Illustratively: 说明性地:

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

but

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

Thus, this: 因此,这:

[1, x][n % 2]

is to multiply the previous recursion by either 1 (for even n case) or x (for odd n case) and is equivalent to ternary expression: 是将前一个递归乘以1 (对于n偶数)或x (对于n奇数),并等效于三元表达式:

1 if n % 2 == 0 else x

This is divide and conquer technique. 这是分而治之的技术。 The implementation above is a fast way of computing exponentiation. 上面的实现是计算幂的快速方法。 At each call, half of the multiplications are eliminated. 在每个调用中,一半的乘法被消除。

Assuming that n is even, x^n can be written as below (If n is odd, it requires one extra multiplication) 假设n为偶数,则x ^ n可以写成如下(如果n为奇数,则需要额外的乘法)

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

The function shown above implements the 1st version. 上面显示的功能实现了第一个版本。 It's easy to implement the 2nd one also (I removed recursion base cases below) 同样也很容易实现第二个(我在下面删除了递归基础案例)

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

The right answer might be below 正确的答案可能在下面

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM