這是CodeSprint3的問題 https://cs3.interviewstreet.com/challenges/dashboard/#problem/50877a587c389 基本上問題是計算給定n和r的可能組合數nCr。 1 < = n < = 1000000000和0 < = r < = n。 輸出所有答案模142857.查找大n(十進制表示精度)的組合數C(n,r)
Since 6C4=6!/4! 2!
=6*5/2!
=6*5/2*1
我認爲可以使用分割在每個step.That避免溢出是 開始用正的值(n爲6在這種情況下)。 遞減n並與先前的值相乘(因此它變成6 * 5) 用分母執行除法,然後遞減(6 * 5/2,分母2變爲1) 重複步驟直到n小於最大值2個分母和迭代次數相同的除數(分母的最低會變成1)
int count(int n,int r)
{int maxDen=r>(n-r)?r:n-r; //larger number in the denominator
int minDen=n-maxDen; //the smaller number in denominator
double num=1;
for(int j=n;j>maxDen;j--)
{num=j*num; //for C(6,4) example num=6*5 and so on
// System.out.println("num "+num +" minDen "+minDen);
num=num/minDen; //divide num 6*5 in this case by 2
minDen--;
}
num=num%142875; //output the result modulo 142875
return (int) num;
}
但或許是由於損失精度多個部門進行,它給出錯誤的值,但隨後它仍然給出了正確的輸出一些值。正如22 17而不是24 17一樣。
(22 17) = 26334 //gives Correct value
(24 17)= 60353 //wrong value correct value is 60390
(25,17)=81450 //wrong value correct value is 81576
(16 15)= 16 //gives correct value
(87 28)= 54384 //wrong value correct value is 141525
我試圖使用num作爲BigDecimal,結果我不得不用BigDecimal替換所有的東西來執行操作。輸出結果與上面代碼中給出正確結果的輸入相同。但對於給出錯誤的輸入結果,程序拋出異常
Exception in thread "main" **java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.**
at java.math.BigDecimal.divide(Unknown Source)
at Combination.NcRcount2.count(NcRcount2.java:16)
at Combination.NcRcount2.main(NcRcount2.java:37)
線16 NUM = num.divide(明登); //替換早期使用的NUM /明登,既NUM和明登都BigDecimal的在這種情況下
即使如果數量沒有一個準確的十進制表示,鑑於BigDecimal的任意精度的結果誤差將有如果它沒有拋出異常,它會被最小化。 ** 如果浮點或雙精度除法運算的結果沒有一個準確的十進制表示,那麼爲什麼不拋出異常?**
我驗證了使用BigDecimal與動態規劃方法的結果
C(n,r)=C(n-1,r-1)+C(n-1,r)
這正常工作在所有情況下,因爲它似乎給我,但必須有一個更好的辦法
BigDecimal Comb (int n, int k)
{ if(k>n-k)
k=n-k;
BigDecimal B[][]=new BigDecimal[n+1] [k+1];
for (int i = 0; i <= n; i++)
{ int min;
if(i>=k)
min=k;
else
min=i;
for (int j = 0; j <= min; j++)
{ if (j == 0 || j == i)
B[i][j] =new BigDecimal(1);
else{
if(j>i-j)
B[i][j]=B[i][i-j];
else
B[i][j] = B[i - 1][j - 1].add(B[i - 1] [j]);
}
}
}
BigDecimal div=new BigDecimal(142857);
return B[n][k].remainder(div);
}
請建議我一個更好的辦法來做到這一點,而不使用設g BigDecimal
有個聲音告訴我, 「*輸出所有的答案模142857 *」 的多,更重要的這裏,不僅輸出。在計算過程中嘗試利用它*。 –
是的,做托馬斯說的話。 – japreiss
複製[Binomial coefficient modulo 142857](http://stackoverflow.com/questions/13106587)它有足夠的答案 –