当n为偶数时针对x ^ n优化的递归方法

时间:2015-09-27 02:05:41

标签: java recursion exponentiation

我需要编写一个使用Java的递归方法,称为power,它接受一个双x和一个整数n并返回x ^ n。这是我到目前为止所拥有的。

public static double power(double x, int n) {
    if (n == 0)
        return 1;
    if (n == 1)
        return x;
    else
        return x * (power(x, n-1));

}

此代码按预期工作。但是,我正在努力加倍努力并执行以下可选练习:

“可选挑战:当n为偶数时,使用x ^ n =(x ^(n / 2))^ 2,可以使此方法更有效。”

当n为偶数时,我不确定如何实现最后一个公式。我不认为我可以使用递归。我试图实现以下内容,但它也不起作用,因为我不能将int的功能加倍。

if (n%2 == 0)
        return (x^(n/2))^2;

有人能指出我正确的方向吗?我觉得我错过了一些明显的东西。所有帮助表示赞赏。

6 个答案:

答案 0 :(得分:23)

它与x ^ n == x *(x ^(n-1))的原理完全相同:为x ^(n / 2)和(...)^插入递归函数2,但要确保你没有输入n == 2的无限递归(因为2也是偶数):

if (n % 2 == 0 && n > 2) 
  return power(power(x, n / 2), 2);
} 

或者,您可以使用中间变量:

if (n % 2 == 0) {
  double s = power(x, n / 2);
  return s * s;
}

我可能只是处理2作为特例 - 并且避免使用"和" -condition和额外变量:

public static double power(double x, int n) {
  if (n == 0) return 1;
  if (n == 1) return x;
  if (n == 2) return x * x;
  if (n % 2 == 0) return power(power(x, n / 2), 2);
  return x * (power(x, n - 1));
}

P.S。我认为这也应该有效:)

public static double power(double x, int n) {
  if (n == 0) return 1;
  if (n == 1) return x;
  if (n == 2) return x * x;
  return power(x, n % 2) * power(power(x, n / 2), 2);
}

答案 1 :(得分:11)

n为偶数时,公式正是您所写的:将n除以2,递归调用power,并对结果求平方。

n为奇数时,公式稍微复杂一些:从1减去n,对n/2进行递归调用,对结果求平方并乘以x

if (n%2 == 0)
    return (x^(n/2))^2;
else
    return x*(x^(n/2))^2;

n/2截断结果,因此1的减法未明确完成。这是Java中的一个实现:

public static double power(double x, int n) {
    if (n == 0) return 1;
    if (n == 1) return x;
    double pHalf = power(x, n/2);
    if (n%2 == 0) {
        return pHalf*pHalf;
    } else {
        return x*pHalf*pHalf;
    }
}

Demo.

答案 2 :(得分:6)

提示:^操作不会在Java中执行取幂,但您编写的函数power将会。

另外,不要忘记平方数字与单独乘以数字相同。无需调用函数。

答案 3 :(得分:6)

对您的函数进行一些小改动,它将减少递归调用的次数:

public static double power(double x, int n) {
    if (n == 0) {
        return 1;
    }
    if (n == 1) {
        return x;
    }

    if (n % 2 == 0) {
        double temp = power(x, n / 2);
        return temp * temp;
    } else {
        return x * (power(x, n - 1));
    }
}

答案 4 :(得分:5)

由于

x^(2n) = (x^n)^2

您可以将此规则添加到您的方法中,使用您编写的幂函数,如Stefan Haustein建议的那样,或使用常规乘法运算符,因为您似乎可以这样做。

注意,不需要基本情况​​n = 1和n = 0,其中一个就足够了(最好使用基本情况n = 0,否则你的方法不会被定义为n = 0)。

public static double power(double x, int n) {
    if (n == 0)
        return 1;
    else if (n % 2 == 0)
        double val = power(x, n/2);
        return val * val;
    else
        return x * (power(x, n-1));
}

在任何情况下都无需检查n> 2。

答案 5 :(得分:0)

这只是提醒我可以进行更多优化 以下代码。

class Solution:
# @param x, a float
# @param n, a integer
# @return a float
def pow(self, x, n):
    if n<0:
        return 1.0/self.pow(x,-n)
    elif n==0:
        return 1.0
    elif n==1:
        return x
    else:
        m = n & (-n)
        if( m==n ):
            r1 = self.pow(x,n>>1)
            return r1*r1
        else:
            return self.pow(x,m)*self.pow(x,n-m)

什么是更多的中间结果可以记忆,避免冗余计算。