为什么我使用递归会出现这个错误?
How come I got this error by using recursion?
如果我输入 33333,我会收到此错误。我检查了很多次,但我不知道如何解决。如果我输入大于 33333 的数字,它工作正常。 33333 怎么了?
我的日志:
Exception in thread "AWT-EventQueue-0" java.lang.WhosebugError
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
}
}
不要使用递归,使用循环。
每次调用一个方法,栈都会增长,最后会变满,这就是为什么说栈溢出。
所以当你认为递归会多次调用同一个方法时,不要使用递归
递归是计算阶乘的一种极其低效的方法,不幸的是,它也被用于几乎所有编程课程的递归介绍中。尝试使用迭代方法!
当我测试它时(当然,在 C# 而不是 Java 中,但语法相同并且它的行为方式相似)我得到了所有相似值的相似错误 - 不只是那个特定的数字。
请记住,每次进行递归调用时,堆栈都会增加,因此通常情况下,如果递归调用过多,您最终会 运行 [=22] =] 仅仅是因为栈变得太大了。
记忆(这需要存储中间结果,这样程序就不必采取那么多步骤;例如,如果你知道 10,000!,你可以在更大的值上保存数千次计算)可以改善这种情况,可以使用尾递归(在支持它的语言中)或者等效地使用 "for" 循环(根本不会增加堆栈)。
还要记住,阶乘最终会变得比 long 或 double 类型所能表示的还要大,因此堆栈溢出异常不会是表示它们的唯一问题。
您的代码超出了堆栈限制,但您可以 "unroll" 递归的一部分。如果您还使用 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));
}
如前所述,结果有点大 post。
如果我输入 33333,我会收到此错误。我检查了很多次,但我不知道如何解决。如果我输入大于 33333 的数字,它工作正常。 33333 怎么了?
我的日志:
Exception in thread "AWT-EventQueue-0" java.lang.WhosebugError
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
}
}
不要使用递归,使用循环。 每次调用一个方法,栈都会增长,最后会变满,这就是为什么说栈溢出。
所以当你认为递归会多次调用同一个方法时,不要使用递归
递归是计算阶乘的一种极其低效的方法,不幸的是,它也被用于几乎所有编程课程的递归介绍中。尝试使用迭代方法!
当我测试它时(当然,在 C# 而不是 Java 中,但语法相同并且它的行为方式相似)我得到了所有相似值的相似错误 - 不只是那个特定的数字。
请记住,每次进行递归调用时,堆栈都会增加,因此通常情况下,如果递归调用过多,您最终会 运行 [=22] =] 仅仅是因为栈变得太大了。
记忆(这需要存储中间结果,这样程序就不必采取那么多步骤;例如,如果你知道 10,000!,你可以在更大的值上保存数千次计算)可以改善这种情况,可以使用尾递归(在支持它的语言中)或者等效地使用 "for" 循环(根本不会增加堆栈)。
还要记住,阶乘最终会变得比 long 或 double 类型所能表示的还要大,因此堆栈溢出异常不会是表示它们的唯一问题。
您的代码超出了堆栈限制,但您可以 "unroll" 递归的一部分。如果您还使用 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));
}
如前所述,结果有点大 post。