减少pow递归方法的递归调用?

时间:2011-03-13 08:54:53

标签: java

关于如何减少pow方法的自我实现的递归调用量的问题。这是我写的,可以改进吗?

public static int pow(double a, int b) {
    boolean isNegative = false;

    if(b < 0) {
        isNegative = true;
    }

    if(b == 0) {
        return 1;
    } 
    else if(b == 1) {
        return (isNegative ? (1 / b) : b);
    }

    return (isNegative ? ((1 / b) * (1 / b) * pow(a, b + 2)) : (b * b * pow(a, b - 2)));
}

3 个答案:

答案 0 :(得分:5)

是的,它可以改进。

以这种方式思考:

  • 如果b是偶数,则a ^ b = a ^(b / 2)* a ^(b / 2)。
  • 如果b是奇数,那么a ^ b = a ^(b / 2)* a ^(b / 2)* a(其中/表示整数除法)。

代码(脑力编译,咖啡尚未开始等):

public static double pow(double a, int b) {
    if (b < 0)
        return 1 / pow(a, -b);
    if (b == 0)
        return 1;
    double halfPow = pow(a, b/2);
    if (b % 2 == 0)
        return halfPow * halfPow;
    else
        return halfPow * halfPow * a;
}

这为您提供了O(log b)递归调用,而不是解决方案中的O(n)。

答案 1 :(得分:1)

查看memoization

答案 2 :(得分:1)

编辑:从根本上说,你有三个问题:

  • 代码不起作用(截至编辑时,它现在完全忽略了a
  • 代码太复杂了
  • 代码递送的次数超出了您的要求

尝试修复其中的第三个而不修复第一个是没有意义的。

你的第一个停靠点应该是一些单元测试。他们会非常迅速地证明您的代码目前已被破坏,并且让您相信当您修复它时,您可以更改它并知道您是否已经破坏了任何内容。

然后你应该旨在简化它。例如,您可以使用以下方法轻松启动方法:

if (b < 0)
{
    return 1 / pow(a, -b);
}

...然后您不再需要担心b的负值。

最后你可以看看你剩下的东西,并尝试将递归解决方案转变为迭代解决方案。