Recursion pow(x,n)的递归方法,用于查找小于10次乘法的2^(37)
pow(x,n)的正则递归方法如下: 功率(x,n):Recursion pow(x,n)的递归方法,用于查找小于10次乘法的2^(37),recursion,Recursion,pow(x,n)的正则递归方法如下: 功率(x,n): 使用这种方法,2^(37)将需要37次乘法。我如何修改它以将乘法数减少到10以下?我认为只有在功能不过度的情况下才能做到这一点 您可以用对数时间而不是线性时间计算数字的幂 int cnt = 0; // calculate a^b int pow(int a, int b){ if(b==0) return 1; if(b%2==0){ int v = pow(a, b/2); cnt +=
使用这种方法,2^(37)将需要37次乘法。我如何修改它以将乘法数减少到10以下?我认为只有在功能不过度的情况下才能做到这一点 您可以用对数时间而不是线性时间计算数字的幂
int cnt = 0;
// calculate a^b
int pow(int a, int b){
if(b==0) return 1;
if(b%2==0){
int v = pow(a, b/2);
cnt += 1;
return v*v;
}else{
int v = pow(a, b/2);
cnt += 2;
return v*v*a;
}
}
通过程序验证,上述代码的乘法数将为9。与invin做的稍有不同,我得到了8个乘法。这是一个Ruby实现。请注意,Ruby方法返回最后计算的表达式的结果。有了这样的理解,它读起来非常像伪代码,但实际上您可以运行它:
$count = 0
def pow(a, b)
if b > 0
$count += 1 # note only one multiplication in both of the following cases
if b.even?
x = pow(a, b/2)
x * x
else
a * pow(a, b-1)
end
else # no multiplication for the base case
1
end
end
p pow(2, 37) # 137438953472
p $count # 8
请注意,调用该方法的幂的顺序是
37 -> 36 -> 18 -> 9 -> 8 -> 4 -> 2 -> 1 -> 0
每个箭头代表一次乘法。计算零次方总是得到1,没有乘法,并且有8个箭头
由于n的偶数值为xn=(xn/2)2=(x2)n/2,因此我们可以推导出这种细微不同的实现:
$count = 0
def pow(a, b)
if b > 1
if b.even?
$count += 1
pow(a * a, b/2)
else
$count += 2
a * pow(a * a, b/2)
end
elsif b > 0
a
else
1
end
end
p pow(2, 37) # 137438953472
p $count # 7
这个版本包含了原始问题中的所有基本情况,很容易运行并确认它在7次乘法中计算2^37,并且不需要任何局部变量分配。当然,对于生产使用,您可以注释掉或删除对
$count
的引用。使用这种方法,您只需7次乘法即可计算2^(37)
功率(x,n):
现在让我们用这种方法计算2^(37)——
2^(37)=
此函数不是过多的,因此它在计算后重用值。因此,计算2^(37)只需要7次乘法。注意,当n为偶数时,xn=(xn/2)**2,或当n为奇数时,乘以x。这是正确的递归调用次数,因为
b
上的算术是正确的,但是,当尝试使用大于30的功率时,实际功率计算溢出了Javaint
。您是否在n个偶数/奇数行上调用了pow
函数两次?@pjs是的,使用了递归。那么,如果您声明以7次乘法计算结果,您就错了。通过在每一级别将递归调用的数量增加一倍,就可以取消将指数减半的工作。如果你不相信它的逻辑,那么试着实现它并计算。您会发现当前的算法实际上执行36次乘法。
$count = 0
def pow(a, b)
if b > 1
if b.even?
$count += 1
pow(a * a, b/2)
else
$count += 2
a * pow(a * a, b/2)
end
elsif b > 0
a
else
1
end
end
p pow(2, 37) # 137438953472
p $count # 7
= 1 ... n=0
= 0 ... x=0
= x ... n=1
= pow(x,n/2) * pow (x,n/2) ... n = even
= x * pow(x,n/2) * pow(x,n.2) ... n = odd
= 2 * 2^(18) * 2^(18)
= 2^(9) * 2^(9)
= 2 * 2^(4) * 2^(4)
= 2^(2) * 2^(2)
= 2 * 2