Java 带有递归的堆栈溢出异常

Java 带有递归的堆栈溢出异常,java,recursion,Java,Recursion,我正在尝试制作一个计算双阶乘的程序(示例-n=3,=>(3!)!=6!=720),但我在递归底部遇到一些问题,并且出现堆栈溢出异常 public static long df(long n) { if (n == 1) { return 1; } else { return df(n * df(n - 1)); } } public static void main(String[] args) { System.out.prin

我正在尝试制作一个计算双阶乘的程序(示例-n=3,=>(3!)!=6!=720),但我在递归底部遇到一些问题,并且出现堆栈溢出异常

public static long df(long n) {
    if (n == 1) {
        return 1;
    } else {
        return df(n * df(n - 1));
    }
}

public static void main(String[] args) {
    System.out.println(df(3));
}

您遇到了一个带有
df(n*df(n-1))的无限循环

n*df(n-1)
将计算阶乘,而您无意中将答案反馈到递归方法中,导致它永远持续下去

改变

return df(n * df(n - 1));

你应该得到阶乘的正确结果



一旦你有了这个有效的递归阶乘方法,通过使用
df(df(3))

我认为你应该在阶乘的帮助下使用相互递归来创建一个双阶乘

一般的g-阶乘函数可以组成阶乘
g
次:

public static long gf(long n, long g) {
    if (g == 1){
        return fact(n);
    }
    return fact(gf(n, g - 1));
}
具体的双阶乘可以是gf(n,2)

和阶乘辅助函数:

public static long fact(long n) {
    if (n == 1) {
        return 1;
    } else {
        return n * fact(n - 1);
    }
}
long double_fac(long n)
{
    long step_one = fac(n);
    return fac(step_one);
}
现在测试:

public static void main(String[] args) {
    System.out.println(df(3));
}

首先,定义阶乘函数:

public static long fact(long n) {
    if (n == 1) {
        return 1;
    } else {
        return n * fact(n - 1);
    }
}
long double_fac(long n)
{
    long step_one = fac(n);
    return fac(step_one);
}
通过Jupyter:

#include <iostream>
std::cout << "some output" << std::endl;

long fac(long n) {
    if( n == 1)
        return 1;
    else
        return n * fac((n-1));
}
我们可以做到:

public static long factorial(long n) {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}

public static long twice_factorial(long n) {
    return factorial(factorial(n));
}
如果希望此函数有用,可以使用浮动近似方程。但在近似值上再次调用近似阶乘可能没有多大意义。您需要嵌套阶乘值本身的浮动近似方程

或者,我们可以切换到
biginger

import java.math.BigInteger;

public class Test {

    public static BigInteger factorial(BigInteger n) {
        return (n.compareTo(BigInteger.ONE) <= 0) ? n : n.multiply(factorial(n.subtract(BigInteger.ONE)));
    }

    public static BigInteger twice_factorial(BigInteger n) {
        return factorial(factorial(n));
    }

    public static void main(String[] args) {
        System.out.println(twice_factorial(new BigInteger(args[0])));
    }
}
但这只涉及(7!)!在我们得到java.lang.StackOverflowerError之前!如果我们想更进一步,我们需要转储递归并迭代计算阶乘:

public static BigInteger factorial(BigInteger n) {
    BigInteger result = BigInteger.ONE;

    while (n.compareTo(BigInteger.ONE) > 0) {
        result = result.multiply(n);

        n = n.subtract(BigInteger.ONE);
    }

    return result;
}
用法

> java Test 4
620448401733239439360000
>
> java Test 8
34343594927610057460299569794488787548168370492599954077788679570543951730
56532019908409885347136320062629610912426681208933917127972031183174941649
96595241192401936325236835841309623900814542199431592985678608274776672087
95121782091782285081003034058936009374494731880192149398389083772042074284
01934242037338152135699611399400041646418675870467025785609383107424869450
...
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000
> 

您建议的解决方案递归计算阶乘-3!=6.但我正在计算这个(3!)!=6! = 720我正在尝试递归两次计算阶乘。@NoSuchUserException从一个方法来看似乎没有一个很好的方法来计算阶乘,但仅使用
df(df(input))
应该可以满足您的需要@phflack谢谢!在术语方面要小心,双阶乘在
n
是1到n个与
n
具有相同奇偶校验(奇偶校验)的数字的乘积。您要做的更像是对阶乘的嵌套调用。
public static BigInteger factorial(BigInteger n) {
    BigInteger result = BigInteger.ONE;

    while (n.compareTo(BigInteger.ONE) > 0) {
        result = result.multiply(n);

        n = n.subtract(BigInteger.ONE);
    }

    return result;
}
> java Test 8
34343594927610057460299569794488787548168370492599954077788679570543951730
56532019908409885347136320062629610912426681208933917127972031183174941649
96595241192401936325236835841309623900814542199431592985678608274776672087
95121782091782285081003034058936009374494731880192149398389083772042074284
01934242037338152135699611399400041646418675870467025785609383107424869450
...
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000
>