计算组合的金额 [英] Calculating the Amount of Combinations

查看:150
本文介绍了计算组合的金额的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

干杯,

我知道你能得到的组合用下面的公式金额(不重复和顺序并不重要):

I know you can get the amount of combinations with the following formula (without repetition and order is not important):

// Choose r from n

n! / r!(n - r)!

不过,我不知道如何实现这在C ++,因为例如用

However, I don't know how to implement this in C++, since for instance with

n = 52

n! = 8,0658175170943878571660636856404e+67

数甚至无符号__int64变得太大了(或无符号长长)。有一些变通方法来实现的公式,没有任何第三方BIGINT-libraries?

the number gets way too big even for unsigned __int64 (or unsigned long long). Is there some workaround to implement the formula without any third-party "bigint" -libraries?

推荐答案

下面是一个古老的算法是准确,不溢出,除非其结果是大的很长很长

Here's an ancient algorithm which is exact and doesn't overflow unless the result is to big for a 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卷的艺术:半数值算法我觉得

This algorithm is also in Knuth's "The Art of Computer Programming, 3rd Edition, Volume 2: Seminumerical Algorithms" I think.

更新:有一个小的可能性,该算法将溢出就行了:

UPDATE: There's a small possibility that the algorithm will overflow on the line:

r *= n--;

非常 n很大。一个天真的上限为的sqrt(的std :: numeric_limits的&LT;长长&GT; :: MAX())这意味着 N 小于rougly 40亿。

for very large n. A naive upper bound is sqrt(std::numeric_limits<long long>::max()) which means an n less than rougly 4,000,000,000.

这篇关于计算组合的金额的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆