干杯,
我知道您可以使用以下公式获得组合的数量(无重复和顺序并不重要):
//从n中选择r n!/ r!(n-r)!
但是,我不知道如何在C ++中实现此功能,因为例如
n = 52 n!= 8,0658175170943878571660636856404e + 67
这个数字对于unsigned __int64(或unsigned long long)来说太大了。在没有任何第三方“ bigint” -libraries的情况下,是否存在一些解决方案来实现该公式?
unsigned __int64
unsigned long long
这是一种精确的古老算法,除非结果太大,否则不会溢出 long long
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。
sqrt(std::numeric_limits<long long>::max())
n