我正在编写计算组合的代码(例如7选择3 = 25),对于代码大战中的kata(https://www.codewars.com/kata/color-choice/train/java),任务是在此公式中找到x的最低值:
m = n choose x
等同于:
m = n! / (x! * (n - x)!)
给出n和m。我的代码适用于int范围内的数字(虽然所有变量都声明为long),但是当数字变大时,除法过程会导致错误的值。
我已经尝试在其他地方寻找答案,为什么大长度的除法会以这种方式产生,但唯一的解决方案是用户用数字定义long的情况,他们在后缀中添加L值,而在我的代码中,没有任何值的直接硬编码。任何人都可以解释为什么我可以为我的计算得到这些结果
代码:
public class Checkchoose {
public static long checkchoose(long m, int n) {
long facN = factorial((long)n);
long calc=0, x=0;
while(calc!=m && x<=n){
x++;
System.out.println("n="+n+" x="+x);
long facX=factorial(x);
long nx = factorial(n-x);
calc=facN/(facX*nx);
System.out.println("facN="+facN+" facX="+facX+" calc="+calc);
}
System.out.println("n="+n+" x="+x+"\n");
if(x>n) return -1;
else return x;
}
public static long factorial(long val){
long out=1;
for(long i=val; i>0; i--) out*=i;
return out;
}
}
代码工作:
m = 184756
n=20 x=1
facN=2432902008176640000 facX=1 calc=20
n=20 x=2
facN=2432902008176640000 facX=2 calc=190
n=20 x=3
facN=2432902008176640000 facX=6 calc=1140
n=20 x=4
facN=2432902008176640000 facX=24 calc=4845
n=20 x=5
facN=2432902008176640000 facX=120 calc=15504
n=20 x=6
facN=2432902008176640000 facX=720 calc=38760
n=20 x=7
facN=2432902008176640000 facX=5040 calc=77520
n=20 x=8
facN=2432902008176640000 facX=40320 calc=125970
n=20 x=9
facN=2432902008176640000 facX=362880 calc=167960
n=20 x=10
facN=2432902008176640000 facX=3628800 calc=184756
20 choose 10 = 184756
代码不起作用:
m = 3268760
n=25 x=1
facN=7034535277573963776 facX=1 calc=0
n=25 x=2
facN=7034535277573963776 facX=2 calc=-3
n=25 x=3
facN=7034535277573963776 facX=6 calc=0
n=25 x=4
facN=7034535277573963776 facX=24 calc=0
n=25 x=5
facN=7034535277573963776 facX=120 calc=-2
n=25 x=6
facN=7034535277573963776 facX=720 calc=-1
n=25 x=7
facN=7034535277573963776 facX=5040 calc=-1
n=25 x=8
facN=7034535277573963776 facX=40320 calc=-1
n=25 x=9
facN=7034535277573963776 facX=362880 calc=0
n=25 x=10
facN=7034535277573963776 facX=3628800 calc=1
n=25 x=11
facN=7034535277573963776 facX=39916800 calc=2
n=25 x=12
facN=7034535277573963776 facX=479001600 calc=2
n=25 x=13
facN=7034535277573963776 facX=6227020800 calc=2
n=25 x=14
facN=7034535277573963776 facX=87178291200 calc=2
n=25 x=15
facN=7034535277573963776 facX=1307674368000 calc=1
n=25 x=16
facN=7034535277573963776 facX=20922789888000 calc=0
n=25 x=17
facN=7034535277573963776 facX=355687428096000 calc=-1
n=25 x=18
facN=7034535277573963776 facX=6402373705728000 calc=-1
n=25 x=19
facN=7034535277573963776 facX=121645100408832000 calc=-1
n=25 x=20
facN=7034535277573963776 facX=2432902008176640000 calc=-2
n=25 x=21
facN=7034535277573963776 facX=-4249290049419214848 calc=0
n=25 x=22
facN=7034535277573963776 facX=-1250660718674968576 calc=0
n=25 x=23
facN=7034535277573963776 facX=8128291617894825984 calc=-3
n=25 x=24
facN=7034535277573963776 facX=-7835185981329244160 calc=0
n=25 x=25
facN=7034535277573963776 facX=7034535277573963776 calc=1
n=25 x=26
facN=7034535277573963776 facX=-1569523520172457984 calc=-4
n=25 x=26
Expected: <10> but was <-1>
25 choose 10 = 3268760