我需要计算一个力量的力量。例如:3 ^ 2 ^ n。您可以将n视为输入,但此示例与9 ^ n不同。我使用循环编写算法,但现在我需要编写递归算法。我找不到一种有效的方法来写它。
答案 0 :(得分:2)
假设x ^(y ^ n)= powpow(x, y, n)
,y和n> = 1
如果y> 1和n> 1,powpow(x, y, n) = powpow(x, y, 1) * powpow(x, y, n-1)
(越接近结果)
如果y> 1和n = 1,powpow(x, y, 1) = x * powpow(x, y-1, 1)
(越来越近)
如果y = 1且n = 1,powpow(x, 1, 1) = x
(已解决)
这比循环效率低,但它是递归的。那是你的目标......?
编辑正如@pjs指出的那样,第一种情况应该是:
powpow(x, y, 1) = powpow(x, powpow(y, n, 1), 1)
答案 1 :(得分:2)
我继续在Ruby中实现这一点,它非常接近伪代码,并具有可测试性的额外好处。由于Ruby还具有任意精度整数运算,因此以下代码适用于非平凡的参数。
这个实现基于对基数进行平方并在指数为偶数时将其提高到指定幂的一半的旧技巧,因此递归堆栈以对数方式而不是线性方式增长。这是受到Ilya的回答的启发,但我发现y > 1 and n > 1
的情况不正确,导致我在下面elif n > 1
行中实现的递归调用中使用递归调用:
def powpow(x, y, n)
if y == 0
return 1
elsif y == 1 || n == 0
return x
elsif n > 1
return powpow(x, powpow(y, n, 1), 1)
elsif y.even?
return powpow(x * x, y / 2, 1)
else
return x * powpow(x * x, y / 2, 1)
end
end
p powpow(3,2,5) # => 1853020188851841
我能够直接确认结果:
irb(main):001:0> 2**5
=> 32
irb(main):002:0> 3**32
=> 1853020188851841
答案 2 :(得分:0)
public class Power {
int ans = 1;
int z = 1;
int x = 1;
int pow1(int b, int c) {
if (c > 1) {
pow1(b, c - 1);
}
ans = ans * b;
return ans;
}
void pow(int a, int b, int c) {
x = pow1(b, c);
ans = a;
pow1(a, x - 1);
}
public static void main(String[] args) {
Power p = new Power();
p.pow(3, 2, 3);
System.out.println(p.ans);
}
}
答案 3 :(得分:0)
递归方法
我们可以使用以下重复计算在复杂度O(log y)中有效地计算功率(x,y):
power(x, y) :
if y is 0 : return 1
if y is even :
return square( power(x, y / 2))
else :
return square( power(x, (y - 1) / 2 ) * x
使用master theorem我们可以将上述过程的复杂度计算为O(log y)(与二分查找类似)。
现在,如果我们使用上述程序来计算3 ^(2 ^ n)。
我们可以看到(2 ^ n)将在O(log n)和3 ^ k中计算。其中k = 2 ^ n,将在O(log k)= O(log(2 ^ n))= O(n)中计算。
因此,顺序使用二进制求幂技巧,我们可以使用O(n)的复杂度来解决这个问题。
迭代方法
想法:假设我们计算了3 ^(2 ^ x)。然后我们可以通过平方3 ^(2 ^ x)轻松计算3 ^(2 ^(x + 1)):
( 3 ^ (2 ^ x) ) * ( 3 ^ (2 ^ x) ) = 3 ^ ( (2 ^ x) + (2 ^ x) )
= 3 ^ ( 2 * (2 ^ x) )
= 3 ^ ( (2 ^ (x + 1) )
所以,如果我们从3 ^(2 ^ 0)开始,在n个步骤中我们可以达到3 ^(2 ^ n):
def solve(n):
ans = 3 ^ (2 ^ 0) = 3
for i in range(0, n) :
ans = square(ans)
return ans
显然,上述解决方案的复杂性也是 O(n)。