pow(x,n)的常规递归方法如下:
pow(x,n):
= 1 ...n=0
= 0 ...x=0
= x ...n=1
= x * pow (x, n-1) ...n>0
采用这种方法,2 ^(37)将需要37次乘法。如何修改此项以将乘法次数减少到10以下?我认为只有在功能不过分的情况下才能做到这一点。
答案 0 :(得分:2)
使用这种方法,您只需 7次乘法即可计算2 ^(37)。
pow(x,n):
= 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 ^(37) -
2 ^(37)=
= 2 * 2^(18) * 2^(18)
= 2^(9) * 2^(9)
= 2 * 2^(4) * 2^(4)
= 2^(2) * 2^(2)
= 2 * 2
此功能不会过多,因此会重复使用一次计算出的值。因此,计算2 ^(37)只需要7次乘法。
答案 1 :(得分:1)
您可以用logN时间而不是线性时间来计算数字的幂。
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;
}
}
由this程序验证的上述代码的乘法次数为9。
答案 2 :(得分:1)
与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
并且每个箭头代表一次乘法。计算零 th 功率总是产生1,没有乘法,并且有8个箭头。
由于x n =(x n / 2 ) 2 =(x 2 ) n / 2 对于n的偶数值,我们可以推导出这种略有不同的实现:
$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
的引用。