【问题标题】:Combination with repetition, differences in calculation结合重复,计算差异
【发布时间】:2011-11-06 07:34:08
【问题描述】:

我有一个小程序。我必须计算重复的组合。
我的代码:

int factorial(int a){

    if (a<0)
    return 0;
    if (a==0 || a==1)
    return 1;
    return factorial(a-1)*a;
}
long int combinationWithRepetion(int n, int k){
    long int a,b,wyn=0;

    wyn=factorial(n+(k-1))/(factorial(k)*factorial(n-1));

    return wyn;
}
int main()
{
    int k,n=0;
    cout<<"Give n: ";
    cin>>n;
    cout<<"Give k: ";
    cin>>k;
    cout<<"combination With Repetion for n="<<n<<
    " k="<<k<<".\n Is equal to "<<combinationWithRepetion(n,k)<<endl;
    return 0;
}

对于 Wolfram alfa 中的 n=9 和 k=6,我得到 3003,但在这个程序中,结果是 44。

对我来说,代码很好。

【问题讨论】:

  • 你会信任谁? Wolfram Alpha 还是你的代码?
  • @MitchWheat,显然是他自己的代码!
  • @MitchWheat 但是你对代码的看法,也许我错过了什么?

标签: c++ math combinations


【解决方案1】:

使用n=9k=6,您可以计算factorial(14),即87,178,291,200,它将溢出一个4 字节的int。如果要使用此公式,则需要使用 long long 之类的内容来获得 8 字节的 int

有更好的计算二项式系数的公式,它们不依赖于计算全阶乘然后进行除法。请参阅Binomial coefficient in programming languages,直接方法(而不是使用递归)。

在 C++ 中,您可以使用:

int binomial(int N, int K) {
  if( K > N - K )
    K = N - K;
  int c = 1;
  for(int i = 0; i < K; ++i) {
    c *= (N - i);
    c /= (i + 1);
  }
  return c;
}

【讨论】:

  • 在具有 64 位 long long 的平台上,对 long long factorial(long long a) 进行一行更改就足以使其工作。
  • @David Schwartz - 这会起作用,但由于阶乘增长如此之快,factorial(21) 会溢出,所以我添加了一个链接,以更好地计算二项式系数而不先计算阶乘。
【解决方案2】:

所以你正在计算 (n+k-1) 选择 k。代入n=9,k=6,就是14choose6(=3003)。但是14!需要超过 36 位来表示,但您的 int 只有 32 位。更好的实现是将 n!/((nk)!k!) 简化为 n(n-1)...(n-k+1)/克!或者你可以使用帕斯卡三角形。

【讨论】:

    猜你喜欢
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    • 2020-10-27
    • 1970-01-01
    • 2018-08-30
    相关资源
    最近更新 更多