Java 我怎么会用递归得到这个错误?

Java 我怎么会用递归得到这个错误?,java,recursion,jframe,stack-overflow,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.

如果我输入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
    }
}
private双阶乘(长数){

如果(number不使用递归,则使用循环。 每次调用一个方法时,堆栈都会增长,最终会变满,这就是为什么它会说堆栈溢出


因此,当您认为它会多次调用同一方法时,不要使用递归

不要使用递归,使用循环。 每次调用一个方法时,堆栈都会增长,最终会变满,这就是为什么它会说堆栈溢出


因此,当你认为递归会多次调用同一个方法时,不要使用递归。

递归是计算阶乘的一种非常不有效的方法,不幸的是,在编程课程中,几乎每一个递归介绍中都会用到它。试着用迭代的方法代替它!

递归是一种非常不有效的计算方法作为一个阶乘,它也不幸地被用于编程课程中几乎每一个递归介绍中。尝试一种迭代方法吧!

当我测试它时(当然,是用C#而不是Java,但语法相同,行为方式相似),我对所有相似的值都会得到一个相似的错误,而不仅仅是那个特定的数字

请记住,每次执行递归调用时,都会增加堆栈,因此通常情况下,如果递归调用过多,堆栈变得过大,最终会耗尽空间

记忆化(需要存储中间结果,这样程序就不必执行那么多步骤;例如,如果你知道10000个,你可以在较大的值上保存数千次计算)可以改善这种情况,使用尾部递归(在支持尾部递归的语言中)或等效的“for”循环也可以改善这种情况(这根本不会增加堆栈)

也请记住,最终阶乘将变得比long或double类型所能表示的还要大,因此堆栈溢出异常将不是表示它们的唯一问题。

当我测试它时(当然,是用C#而不是Java,但语法相同,行为类似)对于所有类似的值,我都会得到一个类似的错误——不仅仅是那个特定的数字

请记住,每次执行递归调用时,都会增加堆栈,因此通常情况下,如果递归调用过多,堆栈变得过大,最终会耗尽空间

记忆化(需要存储中间结果,这样程序就不必执行那么多步骤;例如,如果你知道10000个,你可以在较大的值上保存数千次计算)可以改善这种情况,使用尾部递归(在支持尾部递归的语言中)或等效的“for”循环也可以改善这种情况(这根本不会增加堆栈)


也请记住,最终阶乘将变得比long或double类型所能表示的还要大,因此堆栈溢出异常将不是表示它们的唯一问题。

您的代码超出了堆栈限制,但您可以“展开”递归的一部分。如果你也使用它,你可以计算出非常大的结果。比如

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));
    }
}

如前所述,结果有点大,需要发布。

您的代码超出了堆栈限制,但您可以“展开”部分递归。如果您也使用,您可以计算非常大的结果。例如

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));
    }
}

结果,正如前面提到的,有点大。

我知道使用循环更有效,但是为什么会得到这个错误呢?我知道使用循环更有效,但是为什么会得到这个错误呢?作为阶乘的一个侧面注释,考虑使用.FILE和实现。在你显示的代码中没有问题……你不能再这么深地重复。“我不知道为什么您认为较大的输入会使堆栈溢出消失。您的代码在任何5025或更高的输入上都会溢出。您的程序只是耗尽了调用堆栈。请查看此帖子,了解调用堆栈的部门,了解factorial方法是如何使用long但返回double的???作为factorial的旁注AL,考虑使用.FILE和实现。在显示的代码中没有问题……你不能递归地这么深。我不知道为什么你认为一个更大的输入会使堆栈溢出消失。你的代码在5025或更高的输入上溢出了。你的程序只不过是从调用栈中跑出来。f调用堆栈阶乘方法是如何取长的,但返回双倍的???我不认为这是不幸的-这是一个很好的学习递归函数。许多家庭作业,就其本质而言,有点人为的或有不寻常的约束;它们不应该与你的方式完全相同在“现实世界”中解决问题是的,这是真的,我理解他们为什么要用阶乘和斐波那契序列算法来介绍递归的主题,但我觉得还有很多其他的好例子,说明什么时候可以使用递归算法,递归算法是一个不错的解决方案。比如一个简单的BFS或DFS,几个递归排序算法(当然,如果你第一次学习递归,论文可能会有点多)我不认为这是不幸的——这是一个很好的学习递归函数。许多家庭作业本质上是人为的或有不寻常的限制;它们不应该与你在“现实世界”中解决问题的方式完全相同是的,这是真的,我理解他们为什么要用阶乘和斐波那契序列算法来介绍递归,但我觉得还有很多其他的好例子