一尘不染

计算组合量

algorithm

干杯,

我知道您可以使用以下公式获得组合的数量(无重复和顺序并不重要):

//从n中选择r

n!/ r!(n-r)!

但是,我不知道如何在C ++中实现此功能,因为例如

n = 52

n!= 8,0658175170943878571660636856404e + 67

这个数字对于unsigned __int64(或unsigned long long)来说太大了。在没有任何第三方“ bigint”
-libraries的情况下,是否存在一些解决方案来实现该公式?


阅读 227

收藏
2020-07-28

共1个答案

一尘不染

这是一种精确的古老算法,除非结果太大,否则不会溢出 long long

unsigned long long
choose(unsigned long long n, unsigned long long k) {
    if (k > n) {
        return 0;
    }
    unsigned long long r = 1;
    for (unsigned long long d = 1; d <= k; ++d) {
        r *= n--;
        r /= d;
    }
    return r;
}

我认为,该算法也在Knuth的“计算机编程艺术,第3版,第2卷:半数值算法”中。

更新: 该算法在线上溢出的可能性很小:

r *= n--;

对于 非常 大的n。天真的上限sqrt(std::numeric_limits<long long>::max())意味着n不到4,000,000,000。

2020-07-28