用于计算组合和阶乘的递归函数

时间:2014-12-12 01:45:52

标签: java recursion long-integer

我使用以下两个函数来计算阶乘和组合。

public static long Factorial(long n)
{
    if (n == 0)
        return 1;
    else
        return n * Factorial(n-1);

}

public static long combinations (long n, long k)
{       
    return Factorial(n)/(Factorial(k) * Factorial(n - k));      
}

我正在测试它:

long test = combinations((long)21, (long)13);

它似乎适用于5,2这样的小数字。但如果我尝试21,13,我会得到错误的答案(否定或0)。

有人知道这里发生了什么吗?

3 个答案:

答案 0 :(得分:1)

java中long的最大值为2 ^ 63。

这将安全地将你带到20的阶乘。但是,21的阶乘达到2 ^ 65左右,所以你超过了可以表示的最大值。

如果执行导致溢出的乘法,请参阅this question以了解有关java中发生的情况的讨论。

答案 1 :(得分:1)

这主要是因为来自long(64位已签名)的溢出。您可以在这种情况下查找BigDecimalBigInteger

答案 2 :(得分:0)

正如其他用户所说,长期不能持有Factorial(21)。我使用BigInteger重写了你的Factorial方法,它似乎有效,尽管你必须将BigInteger作为参数传递。

public static BigInteger Factorial(BigInteger n)
{

    if (n.equals(BigInteger.ZERO))
        return BigInteger.ONE;
    else
        return  n.multiply(Factorial(n.subtract(BigInteger.ONE)));
}

然后使用BigInteger重写你的组合方法:

public static BigInteger combinations (BigInteger n, BigInteger k)
{  
        return Factorial(n).divide(Factorial(k).multiply(Factorial(n.subtract(k))));

}

在main方法中,我调用了像这样的组合方法

System.out.print(combinations(new BigInteger("21"), new BigInteger("13")));