C# 计算大数的组合

C# 计算大数的组合,c#,combinations,pascals-triangle,C#,Combinations,Pascals Triangle,我试图计算帕斯卡三角形第100行中的一个特定条目是否可以被3整除。我使用公式nCr计算,其中n=100,r是第100行中的不同条目。 我使用下面的代码来计算组合 public static double Combination(int n, int m, double comb) { for (int r = -1; ++r < m; ) comb = comb * (n - r) / (r + 1); return com

我试图计算帕斯卡三角形第100行中的一个特定条目是否可以被3整除。我使用公式nCr计算,其中n=100,r是第100行中的不同条目。 我使用下面的代码来计算组合

 public static double Combination(int n, int m, double comb)
    {
        for (int r = -1; ++r < m; )
            comb = comb * (n - r) / (r + 1);
        return comb;
    }
公共静态双组合(int n,int m,双梳)
{
对于(int r=-1;++r
但对于像100C16这样的值,我得到了一个包含小数和e的大数字。 我在网上搜索发现实际上有12个数字不能被3整除,但我的程序在第100行给了我63个不能被3整除的数字,这是错误的。谁能告诉我我做错了什么。

我假设“nCr”是n-choose-r的缩写,或者从n中选择r,对吗

要想知道nCr是否可以被3整除,你不需要计算结果,你只需要知道它是否可以被3整除。你要看n有多少次!可以被3整除,然后是r的多少倍!可被3整除,又有多少次(n-r)!是

这真的很简单-1!不能被3,2整除!不是吗,3!一次可除。4.还有5个!也可以一次整除。6.是可除的两倍,7也是可除的!和8!。9! 可以整除4次,依此类推。一直到n(或者不用增量计算就算出公式,这并不难),然后检查

澄清-我的数学是用希伯来语学习的,所以“多少次n!可被3整除”可能不是正确的英语表达方式。“n!可被3m次整除”我的意思是
n=3^m*k
,其中k根本不能被3整除

编辑:一个例子。让我们看看10c4是否可以被3整除

让我们做一张小桌子,上面写着多少次k!可被3整除(k!列仅用于演示,在计算可整除性列时实际上不需要它):

10c4等于10!/(6! * 4!) .

十!!是可除的4倍(意思是10!=3^4*不能被3除的东西), 6.是可除的2倍 4.是可除的1倍


那么10!(6!*4!)可被3整除。实际上是3*70。

首先,你使用双打,我认为这不是个好主意。浮点数会在一段时间后出现错误

如果数量不会增长,那么可以使用以下方法:

public static long nCr (int m, int n) {
    long tmp = 1;
    int j = 2;
    int k = m-n;
    for(int i = m; i > k; i--) {
        tmp *= i;
        while(j <= n && tmp%j == 0) {
            tmp /= j++;
        }
    }
    while(j <= n) {
        tmp /= j++;
    }
    return tmp;
}

你可以争辩说,对于大整数,不需要将除法和乘法交错。但是,如果BigInteger相当大,则对数据的操作将需要一些时间(因为数字表示为字节数的数组)。保持小数值可以避免长时间的计算。

让我们举一个小例子——20c5可以被3整除吗?你能用这个解释一下吗?请与同学分享这个链接。我受够了这个问题。可能重复的
public static long nCr (int m, int n) {
    long tmp = 1;
    int j = 2;
    int k = m-n;
    for(int i = m; i > k; i--) {
        tmp *= i;
        while(j <= n && tmp%j == 0) {
            tmp /= j++;
        }
    }
    while(j <= n) {
        tmp /= j++;
    }
    return tmp;
}
public static BigInteger nCr (int m, int n) {
        BigInteger tmp = 1;
        int j = 2;
        int k = m-n;
        for(int i = m; i > k; i--) {
            tmp *= i;
            while(j <= n && tmp%j == 0) {
                tmp /= j++;
            }
        }
        while(j <= n) {
            tmp /= j++;
        }
        return tmp;
    }