public class PermComb {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Insert n"); int n=input.nextInt();
System.out.println("Insert r"); int r=input.nextInt();
double C = factorial(n)/(factorial(n-r)*factorial(r)); //Finding C.
System.out.println("Therefore: nCr = " + C);
double P = factorial(n)/(factorial(n-r)); //Finding P.
System.out.println("Therefore: nPr = " + P);
}
public static double factorial(double num) {
if(num==1) return 1;
else return num = factorial(num-1)*num;
}
现在它给出了关于(20,10),(30,15),(19,8),(20,2)等值的设定的奇怪答案。
为什么呢?感谢。
答案 0 :(得分:2)
那是因为溢出。你可以存储在int(32位)中的最大数量是2 ^ 31 - 1,大约是20亿。对于长(64位),它将是2 ^ 63 - 1。
要计算30!之类的东西,你需要至少108位。 (基数2对数30!是107.7 ..)
我强烈建议您使用java.math.BigInteger类进行这类计算。
注意:要存储30 C 15的结果,长就足够了。但是对于计算,你需要找到30!你或许可以避免找到30!并且仍然使用一些聪明的算法找到30 C 15。
下面给出了BigInteger的解决方案。
import java.math.BigInteger;
...
public static BigInteger factorial(int num) {
if(num == 0) return BigInteger.ONE;
else return factorial(num - 1).multiply(BigInteger.valueOf(num));
}
public static BigInteger nCr(int n, int r){
return factorial(n).divide(factorial(n-r).multiply(factorial(r));
}
你可以像这样打电话给他们,
BigInteger C = nCr(30, 15);
System.out.println(c);
答案 1 :(得分:1)
阶乘函数溢出了int
已经在13的范围,因此您将无法使用直接使用阶乘的公式。相反,展开阶乘并从替代定义计算nCk:
nCk = n*(n-1)*...*(n-k+1) / k*(k-1)*...*2*1
答案 2 :(得分:0)
使用long
/**
* @author Rakesh KR
*
*/
public class New {
public static void main(String[] args) {
int n=10, r=1;
long ncr,npr;
ncr = find_ncr(n,r);
npr = find_npr(n,r);
System.out.println(ncr+"---"+npr);
}
static long find_ncr(int n,int r){
return factorial(n)/(factorial(r)*factorial(n-r));
}
static long find_npr(int n,int r){
return factorial(n)/factorial(n-r);
}
static long factorial(int n){
return n==0?1:n*factorial(n-1);
}
}