https://www.geeksforgeeks.org/program-to-calculate-the-value-of-ncr-efficiently/
这是我想理解的代码。下面是一个视频,解释它更深入https://www.youtube.com/watch?v=lhxwt7zm3eu ->然而,我仍然不明白它的某个方面。代码如下:
// Java implementation to find nCr
class GFG {
// Function to find the nCr
static void printNcR(int n, int r)
{
// p holds the value of n*(n-1)*(n-2)...,
// k holds the value of r*(r-1)...
long p = 1, k = 1;
// C(n, r) == C(n, n-r),
// choosing the smaller value
if (n - r < r) {
r = n - r;
}
if (r != 0) {
while (r > 0) {
p *= n;
k *= r;
// gcd of p, k
long m = __gcd(p, k);
// dividing by gcd, to simplify
// product division by their gcd
// saves from the overflow
p /= m;
k /= m;
n--;
r--;
}
// k should be simplified to 1
// as C(n, r) is a natural number
// (denominator should be 1 ) .
}
else {
p = 1;
}
// if our approach is correct p = ans and k =1
System.out.println(p);
}
static long __gcd(long n1, long n2)
{
long gcd = 1;
for (int i = 1; i <= n1 && i <= n2; ++i) {
// Checks if i is factor of both integers
if (n1 % i == 0 && n2 % i == 0) {
gcd = i;
}
}
return gcd;
}
// Driver code
public static void main(String[] args)
{
int n = 50, r = 25;
printNcR(n, r);
}
}
具体来说,为什么该代码可以工作:
if (n - r < r)
r = n - r;
为什么通过执行这个简单的操作,在通过并退出主while循环之后最终会产生正确的答案?我不明白为什么这是必要的,为什么这样做是有意义的。比如,为什么没有这个代码会导致ncr计算失败或者不能按预期的方式工作????如果有人能解释这一点,或者给我指一个能解释它的地方,或者数学概念,或者一些很棒的东西:)也许另一种编码同样东西的方法会有所帮助。我只是想理解为什么作为一个数学和编码专业的学生,这会产生正确的答案。为了对我的能力有一点看法(这样你就知道我的水平了),我正在学习面向对象编程,已经完成了高中数学和基础计算机科学。我决不是Maven。
1条答案
按热度按时间s4chpxco1#
这个
nCr
操作有其特殊性,上面的评论中提到了这一点if
条件:// C(n, r) == C(n, n-r)
. 现在,while循环在r>0
每次迭代,r的值递减1
. 所以为了减少循环的执行次数,我们需要减少r的值(如果可能的话)。自C(n, r) == C(n, n-r)
,取其中较小的值r
以及n-r
使迭代次数最小化,但结果保持不变。假设
n = 100
以及r=99
. 在这种情况下,如果我们跳过if
条件,则循环将被执行99
次,而使用if
我们可以更新的条件r
作为r = n-r
以便r=1
,则循环只执行一次。因此,我们正在拯救98
不需要的迭代。因此,如果我们将
if
条件。