为什么我使用递归得到这个错误?

时间:2016-11-07 18:43:03

标签: java recursion jframe stack-overflow

如果我输入33333,我收到此错误。我检查了很多次,但我不知道如何把它弄出来。如果我输入的数字大于33333,它可以正常工作。 33333有什么问题?

我的日志:

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)
at piande.PiandE.factorial(PiandE.java:67)

我的代码:

private double factorial(long number) {
    if (number <= 1) {         // if number is smaller of eaqual to 1 then return directly
        return 1; //factorial of 1 is 1
    } else {
        return number * factorial(number - 1); //using recursion to reuse the method until number be 1
    }
}

4 个答案:

答案 0 :(得分:2)

递归是计算阶乘的一种非常有效的方法,它也很遗憾地用于编程课程中的几乎所有的递归。请尝试迭代方法!

答案 1 :(得分:2)

当我测试它时(在C#而不是Java中授予,但语法相同且行为方式相似)我对所有类似的值都有类似的错误 - not 只是那个特定的号。

请记住,每次进行递归调用都会使堆栈增长,所以通常情况下,如果你有太多的递归调用,你最终会耗尽空间只是因为堆栈变得太大这一事实。

记忆(需要存储中间结果,以便程序不必采取尽可能多的步骤;例如,如果你知道10,000!,你可以在更大的值上保存数千个计算)可以改善这种情况,可以使用尾递归(在支持它的语言中),或者等效地使用&#34;对于&#34;循环(根本不会增加堆栈)。

请记住,最终阶乘将变得比长或双类型所代表的更大,因此堆栈溢出异常不会成为代表它们的唯一问题。

答案 2 :(得分:0)

不要使用递归,请使用循环。 每次调用方法时,堆栈都会增长,最终会变满,这就是堆栈溢出的原因。

所以当你认为它会多次调用相同的方法时,不要使用递归

答案 3 :(得分:0)

您的代码超出了堆栈限制,但您可以&#34;展开&#34;递归的一部分。如果您还使用BigInteger,则可以计算出非常大的结果。像,

private static BigInteger factorial(long number) {
    if (number <= 1) {
        return BigInteger.ONE;
    } else if (number > 7) {
        return BigInteger.valueOf(number)//
                .multiply(BigInteger.valueOf(number - 1))//
                .multiply(BigInteger.valueOf(number - 2))//
                .multiply(BigInteger.valueOf(number - 3))//
                .multiply(BigInteger.valueOf(number - 4))//
                .multiply(BigInteger.valueOf(number - 5))//
                .multiply(BigInteger.valueOf(number - 6))//
                .multiply(factorial(number - 7));
    } else {
        return BigInteger.valueOf(number).multiply(factorial(number - 1));
    }
}

我和

一起跑
public static void main(String args[]) {
    System.out.println(factorial(33333));
}

如上所述,结果有点大。