[英]What is the time complexity of calculating factorial n! using Java's BigInteger
[英]Java Compute C(n,k) and factorial with biginteger
我想計算C(n,k)的答案,例如C(10,2)= 10 * 9/2 * 1 = 45如果我用10這樣的小數測試我的代碼,則該代碼有效。 但是,當我嘗試計算C(1000,900)時,它會編譯
線程“主”中的異常java.lang.ArithmeticException:/零
我見過有人說應該使用BigInteger
,但是嘗試之后,它仍然有錯誤。
例如:我將int factorial
更改為BigInteger factorial
,而cSelect
的for循環則無法將int i
更改為BigInteger
類型,結果,答案up/factorial(y)
出錯。
請幫助我解決此問題。 謝謝!!
public class Test {
// Write a factorial function
static int factorial(int m) {
int result =1;
for (int i=2; i<=m; i++) {
result = result*i;
}
return result;
}
// Caculate C(x,y)
static int cSelect(int x, int y) {
int up=1;
for(int i=x; i>=(x-y+1); i--) {
up = up*i;
}
return up/factorial(y);
}
public static void main(String[] args) {
System.out.println(cSelect(1000,900));
}
}
您的代碼很容易轉換為factorial
。 以ONE
開頭,為循環中的每個i
乘以BigInteger.valueOf(long)
。 喜歡,
// Write a factorial function
static BigInteger factorial(int m) {
BigInteger result = BigInteger.ONE;
for (int i = 2; i <= m; i++) {
result = result.multiply(BigInteger.valueOf(i));
}
return result;
}
您的其他函數的功能完全相同 ,再加上除因factorial(y)
的結果。 喜歡,
// Caculate C(x,y)
static BigInteger cSelect(int x, int y) {
BigInteger up = BigInteger.ONE;
for (int i = x; i >= (x - y + 1); i--) {
up = up.multiply(BigInteger.valueOf(i));
}
return up.divide(factorial(y));
}
沒有其他改變,我得到了
63850511926305130236698511142022274281262900693853331776286816221524376994750901948920974351797699894319420811933446197797592213357065053890
我認為是正確的。
您必須使用BigInteger進行計算。
您嘗試計算的值大約為6.385051192630516e + 139,並且不能表示為Java基本整數值。
即使結果可以表示,但除以零錯誤的原因是除數表達式900! ∗ 100!
900! ∗ 100!
溢出到零。 然后,您將其除以零。
它溢出到零的原因是它可以被2 ^ 32和2 ^ 64整除。 可以通過使用一些簡單的代數來計算900中2的因數的數量來證明! 和100!
首先,返回值必須為BigInteger
,因為C(1000,900)
遠遠超出int
的范圍。
其次,您不需要單獨的factorial()
方法。 迭代時進行除法將通過不創建過大的中間值(以進行多次除法為代價,但實際上可能更快)來改善內存占用。
像這樣:
static BigInteger cSelect(int x, int y) {
BigInteger v = BigInteger.ONE;
for (int i = x, j = 1; j <= y; i--, j++)
v = v.multiply(BigInteger.valueOf(i)).divide(BigInteger.valueOf(j));
return v;
}
通過將i
向下計數和j
向上計數,除法將永遠不會占一小部分。
測試
System.out.println(cSelect(10, 2));
System.out.println(cSelect(1000, 900));
產量
45
63850511926305130236698511142022274281262900693853331776286816221524376994750901948920974351797699894319420811933446197797592213357065053890
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.