我现在有2个函数,其中之一是编写一个简单的递归函数,该函数将在n个步骤中计算指数
第二个函数是我的主要问题,是n / 2个步骤。我对如何协商或控制由n表示的递归调用数感到困惑。
这是一个作业问题,我不允许使用任何形式的循环,只有在那时才允许使用“ while”和“ for”循环,所以请对我轻松一点,因为我知道它看起来很简单。
def simple_recursive_power(x, n):
print("n="+str(n))
if n ==1:
return x
else:
return x* simple_recursive_power(x,n-1)
print("the simple recurse method="+ str(simple_recursive_power(3,3)))
""the above works, the one below is working the wrong way""
def advanced_recursive_power(x, n):
print("n="+str(n))
if n <= 1:
return x
else:
return x * advanced_recursive_power(x, n-1/2)
print("advanced recursion="+ str(advanced_recursive_power(3,3)))
答案 0 :(得分:1)
占据一半周期的更好的指数函数不仅需要调整N,还需要更好的算法。
简单的指数是这样的:走N步,每一步乘以X。
如果要将步数减半,需要注意的关键细节是,如果乘以X * X,则一次要两个步。。
def advanced_recursive_power(x, n):
print("n="+str(n))
if n == 0:
return 1
elif n == 1:
return x
else:
return x * x * advanced_recursive_power(x, n - 2)
现在,这减少了函数调用的次数,但减少了乘法的次数:例如,对于N = 7,我们从X * X * X * X * X * X * X
到X * (X * X) * (X * X) * (X * X)
。如果我们可以预先计算X * X
,那么实际上也可以减少乘法运算...这将计算(X2 = X * X); X * X2 * X2 * X2
,它有四个乘法,而不是七个:
def super_advanced_recursive_power(x, n):
print("n="+str(n))
if n % 2 == 0:
start = 1
else:
start = x
return start * simple_recursive_power(x * x, n // 2)
答案 1 :(得分:0)
如果您接通电源,则可以大大减少步骤数:
def arp(x, n):
"""Advanced recursive power equivalent to x ** n"""
print('#', x, n)
if n == 0:
return 1
elif n == 1:
return x
elif n % 2: # odd exponential
return x * arp(x * x, (n - 1) // 2)
else: # even exponential
return arp(x * x, n // 2)
这仅需O(log n)个步骤。
>>> arp(3, 15)
# 3 15
# 9 7
# 81 3
# 6561 1
14348907
这等效于将加法表示为一系列的减量和增量:
def recursive_add(x, y):
if y == 0:
return x
return (x + 1, y - 1)
这使用了x + y == (x + 1) + (y - 1)
。同样,对于幂,关系x ** n == (x * x) ** (n / 2)
成立。虽然加法(线性)相当慢,但幂(指数)却很快。
这种利用甚至可以增强重复条款的功能。例如,2**8
可以写为((2 * 2) * (2 * 2)) * ((2 * 2) * (2 * 2))
-注意术语2 * 2
和(2 * 2) * (2 * 2)
的重复方式。我们可以将2**8
重写为((2 ** 2) ** 2) ** 2
。这恰好是指数的最后一项递归计算的结果。
对于奇指数,我们有一个问题,例如从2 ** 3
到4 ** 1.5
。因此,我们使用x ** n == x * (x ** (n - 1))
从奇数到偶数。由于我们排除了n == 1
的情况,因此我们知道n >= 3
,因此直接进行x * x, (n-1) // 2
是安全的。
最终结果是,每一步n减半,而不仅仅是一次。