Java 用递归法求一个数的阶乘

Java 用递归法求一个数的阶乘,java,recursion,Java,Recursion,我有下面的递归函数来计算一个数的阶乘。程序运行良好,除非我删除if条件。有人能解释一下原因吗 这就是工作正常的代码- public static long factUsingRecursion(int number) { if (number == 1) { return 1; } else { return number * factUsingRecursion(number - 1); } } 如果没有引发错误的if条件代码 publ

我有下面的递归函数来计算一个数的阶乘。程序运行良好,除非我删除if条件。有人能解释一下原因吗

这就是工作正常的代码-

public static long factUsingRecursion(int number) {
    if (number == 1) {
        return 1;
    } else {
        return number * factUsingRecursion(number - 1);
    }
}
如果没有引发错误的if条件代码

public static long factUsingRecursion(int number) {
    return number * factUsingRecursion(number - 1);
}
我得到堆栈溢出错误

主线程java.lang.StackOverflowerr中出现异常 factusingrecursion.factusingrecursion.java:10


请专家们告诉我为什么会出现这种情况?

在递归中,必须始终存在停止递归的基本情况。没有if,就没有基本情况,也没有什么可以阻止它。最终,堆栈上的方法调用太多,导致StackOverflower错误。

它失去了使递归函数递归的一个因素,因为它没有退出条件

所有递归解必须满足三个规则或属性: 递归解决方案必须包含基本情况。 递归解决方案必须包含递归案例。 递归解决方案必须向基本情况迈进

From:使用Python的数据结构和算法这一行导致数字变量减少1

return number * factUsingRecursion(number - 1);
它将处理除1以外的所有数值

所以这行代码是一个中断条件

if (number == 1) {
        return 1;
}


它可以防止您避免堆栈溢出异常

递归需要基本情况。如果没有它,它将继续一遍又一遍地调用函数,并且永远不会停止。if语句是终止递归的基本情况。这就是为什么如果你删除它,你会得到一个StackOverflower错误。

当你删除if条件时,程序将不再工作,因为你只剩下返回号*factUsingRecursionnumber-1;这里的factUsingRecursionnumber-1将具有相同的返回调用返回号*factUsingRecursionnumber-1;。您的函数不断地调用自身,永远无法对任何内容求值。通过设置条件,您的函数能够在递归链中的某个点求值为确定值,并且第一次调用可以求值。

想象一下调用时会发生什么:

factUsingRecursion(3);
如果:

3*factUsingRecursion(2)
3*2*factUsingRecursion(1)
3*2*1
如果没有if:

3*factUsingRecursion(2)
3*2*factUsingRecursion(1)
3*2*1*factUsingRecursion(0)
3*2*1*0*factUsingRecursion(-1)
3*2*1*0*-1*factUsingRecursion(-2)
3*2*1*0*-1*-2*factUsingRecursion(-3)
...
And so on... It will not stop until you encounter the StackOverflow error

对于每个整数i,您使用i-1调用函数。整数a是无限的,因此您永远不会停止调用该函数。例如:-1000将调用-1001,只要JVM在其堆栈中有一些空间,这将继续进行。

提示:如果没有if,如何决定何时停止?任何递归都应该始终有一个基本条件来结束递归。如果条件仅适用于基本条件。否则它将成为一个无限递归。long不限于正数。计算机会做你让他们做的任何事情……所以,当数字等于1时,函数不会神奇地停止。如果没有if语句,则将函数一个接一个地推到堆栈上,而没有任何语句返回和结束递归的机会。数字将朝着负无穷大的方向前进,直到堆栈溢出。在一个问题中,您只能选择一个可接受的答案。非常感谢。现在很清楚了。感谢您的快速回复@用户2341013不客气。顺便说一句,在StackOverflow上,您只能接受绿色复选标记的一个答案,因此选择对您帮助最大的答案。你可以向上投任意多的答案。当然,我知道了。非常感谢。然而,在这种情况下,所有的答案都帮助了我;