![](/img/trans.png)
[英]How to convert string to number in java ? But i am not looking for hashCode as it wont give unique number. at least i want math logic for same
[英]Java combination function has a limit of small number. How to use math Big int?
這些天我自己在學習java。 此功能用於計算組合。 但是,我發現此函數中的數字n和k的限制非常小。 每次如果我輸入一個大的n或k,例如100,它就會給我
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Combination.combination(Combination.java:29)
at Combination.main(Combination.java:47)
或者給我一個負數......
有沒有辦法使它適用於像10000這樣的大數?
謝謝!
import java.util.HashMap; import java.util.Map;
public class Combination {
private Map<Long,Long> factorialMap = new HashMap<Long,Long>();
public Long getFactorial(int number) {
Long val = factorialMap.get(number);
if(val != null) {
return val;
} else {
val = getFactorialRecursive(number);
factorialMap.put((long) number, val);
return val;
}
}
public Long getFactorialRecursive(int number) {
if(number == 1 || number == 0) {
return 1L;
} else {
return number * getFactorialRecursive(number-1);
}
}
public Long combination(int fromVal, int chooseVal) {
return getFactorial(fromVal)/(getFactorial(chooseVal)*getFactorial(fromVal-chooseVal));
}
public static void main(String[] args) {
int n, k;
Combination comb = new Combination();
java.util.Scanner console = new java.util.Scanner(System.in);
while (true) // will break with k > n or illegal k or n
{ System.out.print ("Value for n: ");
n = console.nextInt();
if ( n < 0 ) break;
System.out.print ("Value for k: ");
k = console.nextInt();;
if ( k > n || k < 0 )
break;
System.out.print(n +" choose " + k + " = ");
System.out.println(comb.combination(n,k));
}
console.nextLine(); // Set up for "Press ENTER...
} }
您應該使用BigInteger
對象: http : //docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html
特別是,你的問題是21! 太長了太長,因此溢出。 另一種選擇是使用double,但這會失去精度,因此如果你需要整數精度, BigInteger
就是你要走的路。
使用BigInteger
您需要將整數轉換為BigInteger
:
BigInteger bi = new BigInteger(intVal+"");
然后使用add
, multiply
, divide
和subtract
(以及其他)來操縱你的值(比如):
bi = bi.add(bi2);
然后你可以使用方法longValue()
來獲取值(假設它適合長):
return bi.longValue();
我建議你認為默認情況下Java不會超過10,000次,而你首先不需要計算這么大的因子。
例如1000!/ 999! 是1000
如果你使用循環,你可以提前停止。
public static BigInteger combination(int n, int r) {
if (r * 2 > n) r = n - r;
BigInteger num = BigInteger.ONE;
BigInteger nr = BigInteger.valueOf(n - r);
for (int i = n; i > r; i--) {
num = num.multiply(BigInteger.valueOf(i));
while (nr.compareTo(BigInteger.ONE) > 0 && num.mod(nr).equals(BigInteger.ZERO)) {
num = num.divide(nr);
nr = nr.subtract(BigInteger.ONE);
}
}
while (nr.compareTo(BigInteger.ONE) > 0) {
num = num.divide(nr);
nr = nr.subtract(BigInteger.ONE);
}
return num;
}
順便說一下,當我的意思是long
使用效率較低時,我不會使用Long
。
為了比較,我使用long包含了相同的代碼。
public static long combination2(int n, int r) {
if (r * 2 > n) r = n - r;
long num = 1;
int nr = n - r;
for (int i = n; i > r; i--) {
num *= i;
while (nr > 1 && num % nr == 0) {
num /= nr--;
}
}
while (nr > 1)
num /= nr--;
return num;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.