它是从我想要计算1+2+3+...+n
和
我很容易想出一个递归方法来处理repeat-plus-operation,代码如下:
public long toAccumulate(long num)
{
return num == 1 ? 1 : num + toAccumulate(num-1);
}
此方法在1
到100
这样的小数字范围内使用时效果很好,但是,当参数达到像1000000
这样的大数字时,它无法正常工作。
我想知道为什么?
一个导致另一个,我写了一个重复次数操作方法如下:
public long toTimes(long num)
{
return num == 1 ? 1 : num * toTimes(num-1);
}
这里有一些有趣的结果。如果我将100
作为参数传递,我将获得0
。所以我减少了参数的值,当参数传递60时我终于得到了一些数字,但结果是一个非常奇怪的负数-8718968878589280256
。
这让我思考,但是我没有太多时间重新思考我从C
学到的东西,这是long long
大数据值类型。我假设显示负数是因为结果数据太大而无法适应当前数据类型。令我感到惊讶的是我意识到Java中有一个BigInteger
类,我记得这个类可以操作大值数据,所以我改变了第一个代码如下:
public BigInteger toAccumulate(BigInteger num)
{
return num.equals(1) ? BigInteger.valueOf(1) : (num.add(toAccumulate(num.subtract(BigInteger.valueOf(1)))));
}
但它仍然没有用......这让我发疯了......
A question I found in the stack overflow which similar to mine 据回答这个问题的人说,我想这可能与导致我的代码中的错误的原因相同。
但是由于BigInteger
类不起作用,我认为这必须是解决这种累积问题的方法。
当您需要积累一些数字并防止它超出最大数据类型时,您会做什么?但这真的是数据类型问题吗?
答案 0 :(得分:1)
return num.equals(1)
? BigInteger.valueOf(1)
: (num.add(toAccumulate(num.subtract(BigInteger.valueOf(1)))));
应该是
return num.equals(BigInteger.valueOf(1))
? BigInteger.valueOf(1)
: (num.add(toAccumulate(num.subtract(BigInteger.valueOf(1)))));
...虽然坦率地说我会把它写成接受int
并返回BigInteger
的方法。
答案 1 :(得分:0)
如果您尝试这样做怎么办:
public static BigInteger toAccumulate (BigInteger num)
{
if (num.equals(BigInteger.valueOf(1)))
{
return BigInteger.valueOf(1) ;
}
else
{
// 1+2+...+(n-1)+n = (n)(n+1)/2
BigInteger addOne = num.add(BigInteger.valueOf(1));
return num.multiply(addOne).divide(BigInteger.valueOf(2));
}
}
以下是如何做1 * 2 * 3 * .... *(n-1)* n
public static BigInteger toTimes (BigInteger num)
{
// Should check for negative input here
BigInteger product = num;
// while num is greater than 1
while (num.compareTo(BigInteger.valueOf(1)) == 1)
{
BigInteger minusOne = num.subtract(BigInteger.valueOf(1));
product = product.multiply(minusOne);
num = minusOne; // num--;
}
return product;
}
注意:这基本上是Factorial Function