📜  有效地计算nCr值的程序

📅  最后修改于: 2021-04-27 22:14:58             🧑  作者: Mango

给定两个数字n,r(n> = r)。任务是为大的n值找到C(n,r)的值。

例子:

Input: n = 30, r = 15
Output: 155117520
C(30, 15) is 155117520 by  30!/((30-15)!*15!)


Input: n = 50, r = 25
Output: 126410606437752

方法:可以使用以下知识创建一个简单的代码:

C(n, r) = [n * (n-1) * .... * (n-r+1)] / [r * (r-1) * .... * 1]

但是,对于较大的n值,r可能会溢出,因此在每次迭代期间,我们将保持产品价值的当前变量除以它们的gcd。

以下是所需的实现:

C++
// C++ implementation to find nCr
#include 
using namespace std;
 
// Function to find the nCr
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 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) {
            p *= n;
            k *= r;
 
            // gcd of p, k
            long 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
    cout << p << endl;
}
 
// Driver code
int main()
{
    int n = 50, r = 25;
 
    printNcR(n, r);
 
    return 0;
}


Java
// 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);
    }
}


Python3
# Python3 implementation to find nCr
 
from math import *
 
# Function to find the nCr
 
 
def printNcR(n, r):
 
    # p holds the value of n*(n-1)*(n-2)...,
    # k holds the value of r*(r-1)...
    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):
            p *= n
            k *= r
 
            # gcd of p, k
            m = gcd(p, k)
 
            # dividing by gcd, to simplify product
            # division by their gcd saves from
            # the overflow
            p //= m
            k //= m
 
            n -= 1
            r -= 1
 
        # 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
    print(p)
 
 
# Driver code
if __name__ == "__main__":
    n = 50
    r = 25
 
    printNcR(n, r)
 
# this code is contributed by
# ChitraNayal


C#
// C# implementation to find nCr
 
using System;
 
public 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
        Console.WriteLine(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
    static public void Main()
    {
        int n = 50, r = 25;
        printNcR(n, r);
    }
    // This code is contributed by ajit.
}


PHP
 0) {
                $p *= $n;
                $k *= $r;
 
                // gcd of p, k
                $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
        echo ($p);
    }
 
    function  __gcd($n1, $n2) {
         $gcd = 1;
 
        for ($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
        $n = 50;
        $r = 25;
        printNcR($n, $r);
 
 
//This code is contributed by Sachin.
 
?>


Javascript


输出
126410606437752

时间复杂度: O(R Log N)
辅助空间: O(1)