析因方法 - 递归还是迭代? (JAVA)

时间:2012-06-23 17:43:39

标签: java recursion iteration

我正在通过项目Euler,我遇到了一个组合问题。组合逻辑意味着计算阶乘。所以,我决定创建一个阶乘方法。然后我遇到了一个问题 - 因为我可以很容易地使用迭代和递归来做这个,我应该去哪一个?我很快写了两个方法 - 迭代:

public static long factorial(int num) {
        long result = 1;
        if(num == 0) {
            return 1;
        }
        else {
            for(int i = 2; i <= num; i++) {
                result *= i;
            }
            return result;
        }

和递归:

public static long factorial(int num) {
        if(num == 0) {
            return 1;
        }
        else {
            return num * factorial(num - 1);
        }
    }

如果我(显然)在这里谈论速度和功能,我应该使用哪一个?而且,一般来说,这种技术通常比其他技术更好(所以如果我以后遇到这个选择,我应该去做什么)?

4 个答案:

答案 0 :(得分:13)

两者都是绝望的天真。没有认真应用factorial会使用任何一个。我认为对于大n来说两者都是低效的,当参数很大时,intlong都不够。

更好的方法是使用良好的gamma function实施和记忆。

Here's Robert Sedgewick的实施。

大值将需要对数。

答案 1 :(得分:0)

每当你得到一个在递归和迭代之间选择的选项时,总是去迭代,因为

1.Recursion涉及创建和销毁堆栈帧,这需要很高的成本。

2.如果你使用的是非常大的值,你的筹码可能会爆炸。

所以只有在你有一些非常诱人的理由时才去递归。

答案 2 :(得分:0)

对于这个问题,没有“这更好,更糟糕”。因为现代计算机非常强大,所以在Java中,它往往是你个人喜欢的。您正在迭代版本中执行更多检查和计算,但是您在递归版本中将更多方法堆积到堆栈中。每个人的利弊,所以你必须逐个采取。

就个人而言,我坚持使用迭代算法来避免递归逻辑。

答案 3 :(得分:0)

我实际上是按时间因素分析这个问题。 我做了2个简单的实现:

迭代:

private static BigInteger bigIterativeFactorial(int x) {
    BigInteger result = BigInteger.ONE;
    for (int i = x; i > 0; i--)
        result = result.multiply(BigInteger.valueOf(i));
    return result;
}

和递归:

public static BigInteger bigRecursiveFactorial(int x) {
    if (x == 0)
        return BigInteger.ONE;
    else
        return bigRecursiveFactorial(x - 1).multiply(BigInteger.valueOf(x));
}

测试两个都在单线程上运行。 事实证明,Iterative仅在使用小参数时稍快一些。当我把n大于100的递归解决方案更快。 我的结论?你永远不能说迭代解决方案比JVM上的递归更快。 (仍然只谈时间)

如果您有兴趣,我会得到这个结论HERE

如果您对更深入了解这两种方法之间的差异感兴趣,我在knowledge-cess.com

上找到了非常好的描述
相关问题