【问题标题】:Different output for binomial coefficient function C++二项式系数函数C ++的不同输出
【发布时间】:2017-10-29 20:49:33
【问题描述】:

我使用两种方法来计算二项式系数。 一个是

int fac(int n) {
if ( n < 2 ) return 1; // return 1 when n=0,1
int ret = 1;
for(int i=2; i <= n; ++i)
    ret *= i;  // calculate factorial
return ret;
}
int choose_fac(int n, int k) {
  return fac(n)/fac(k)/fac(n-k);
}

另一个是:

int choose_dp(int n, int k) {
  int C[n+1][k+1];
  int i, j;
  for (i = 0; i <= n; i++) {
        for (j = 0; j <= min(i, k); j++) {
            if (j == 0 || j == i) C[i][j] = 1;
            else C[i][j] = C[i-1][j-1] + C[i-1][j];
        }
  }
  return C[n][k];
}

所以当我在 (15,5) 上运行时,第二个给出正确答案,而第一个给出 4。我知道对于 choose_fac,int 在计算 15 时超出范围!但如果这是原因,为什么choose_dp没有返回错误的答案,因为它们都使用int来定义函数?

非常感谢!

E.

【问题讨论】:

  • 好吧,choose_dp 不计算 15!。只是因为 n!不能表示为 int 并不意味着 nCk 不能表示为 int

标签: c++ int range long-integer


【解决方案1】:

第一个溢出int

当你调用fac(15)计算choose_fac(15, 5)函数应该计算的值时,1,307,674,368,000大大超出了int的范围。计算 15 choose 5 的最终结果将在 int 的范围内,因为两个相对较大的阶乘被除,但中间结果中的错误会阻止此计算成功完成。

使用动态规划的第二个函数没有这个问题,因为它不显式计算阶乘。这种计算二项式系数的方法称为Pascal's Triangle

【讨论】:

  • 感谢您的解释。但是在计算 (30,15) 哪个结果应该超出范围时,choose_dp 也有效。这要怎么解释?
  • 如果您在计算结束时包含一个显示C 状态的表格,则可能会更清楚地表明choose_dp 永远不会处理大量数字。
  • @Eleanor 30 choose 15 只有 155,117,520,很适合 int。
【解决方案2】:

当你返回 fac(n)/fac(k)/fac(n-k);它从左到右进行评估。 (((fac(n)) /fac(k))/fac(n-k)) 第一次评估 fac(n) 给出了溢出错误。

【讨论】:

  • 感谢您的解释。但是在计算 (30,15) 哪个结果应该超出范围时,choose_dp 也有效。这要怎么解释?
  • Pascal 的三角形在深度 30 处使用,最大值约为 7000 万,而 4byte int 可以包含 20 亿而不会溢出。 int 使用多少字节取决于您的系统。 15 的阶乘约为 1 万亿,要大得多。
猜你喜欢
  • 2023-02-20
  • 2013-10-13
  • 2020-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多