pow(x,n)的递归方法用于找到具有少于10次乘法的2 ^(37)

时间:2014-05-03 04:55:38

标签: recursion

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以下?我认为只有在功能不过分的情况下才能做到这一点。

3 个答案:

答案 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的引用。