【问题标题】:Why is the following code wrong? binomial coefficient为什么下面的代码是错误的?二项式系数
【发布时间】:2016-10-25 15:28:34
【问题描述】:

我正在做项目 euler,我现在遇到问题 15,这是一个链接: https://projecteuler.net/problem=15 。我试图用二项式系数来解决这个问题。这是一个解释它的网站:http://www.mathblog.dk/project-euler-15/。您可以在底部找到它。

我的问题是,为什么下面的代码是错误的?由于这遵循我认为的数学算法:n-k+i/i

        int grid = 20;
        long paths = 1;
        for (int i = 0; i < grid; i++)
        {
            paths *= (grid * 2) - (grid + i)
            paths /= (i + 1);
        }
        Console.WriteLine(paths);
        Console.ReadKey();

为什么这段代码是错误的?这与 mathblog 网站完全相同,但只有 1 行。

        int grid = 20;
        long paths = 1;
        for (int i = 0; i < grid; i++)
        {
            paths *= ((grid * 2) - i) / (i + 1);
        }
        Console.WriteLine(paths);
        Console.ReadKey();

但是为什么这段代码是正确的呢?是不是和前面的代码一样?它不完全遵循数学算法吗?因为是n-k+i/i,而这段代码做n-i/i

       int grid = 20;
        long paths = 1;
        for (int i = 0; i < grid; i++)
        {
            paths *= ((grid * 2) - i);
            paths /=  (i + 1);
        }
        Console.WriteLine(paths);
        Console.ReadKey();

谢谢各位!

【问题讨论】:

  • 尝试使用double paths 而不是long。只要是整数,您的问题可能是除法中的向上舍入
  • 您的第二个代码块与您链接的 URL 中的代码不同。如果你想单行的话,应该是paths = (paths * (grid * 2) - i) / (i + 1);。你写的和paths = paths * (((grid * 2) - i) / (i + 1));一样
  • (grid * 2) - (grid + i) => (2 * grid - grid) - i => grid - i
  • 第二个代码和最后一个代码不一样的原因是您使用的是整数运算。
  • 不,不是 - 只需将一些数字插入 - grid = 20, i = 1 然后你会看到 (2 * 20) - (20 -1) = (40 - 19) = 21, (2 * 20) - 1 = 39

标签: c# algorithm grid binomial-coefficients


【解决方案1】:

如果要组合计算应该是这样的

paths = (path *((grid * 2) - i))/(i + 1);

【讨论】:

  • 谢谢!你知道为什么它不是 (grid * 2) - (grid + i) 而不是 (grid * 2) - i 在正确的代码中吗?
  • 查看我的评论 - 您的代码简化为 (grid - i)
【解决方案2】:

按照惯例,在许多编程语言中,int/int 给出的是 int,* 而不是浮点数。您的方法意味着“路径”应该采用非整数值。事实上,这三种方法都不应该起作用,但巧合的是,最后一种方法起作用了:基本上是因为“路径”的所有中间值也恰好是二项式系数。

调试建议:让你的程序输出中间值。这很有帮助。

*:作为一名数学家,我几乎从不需要这个功能。事实上,其他约定(int/int -> double)平均而言会让我作为程序员的生活更轻松。


我看过你提到的博客。这使您的信息更容易理解。 博客中提到了一个公式:i 从 1 到 k 的 (n-k+1)/i 的乘积。 所以要模仿它,你需要写

    for (int i = 1; i <= grid; i++) // bounds!
    {
        paths *= (grid * 2) - (grid - i) // minus sign!
        paths /= (i + 1);
    }

关于这适用于整数的事实:这是一个意外,因为在产品的中间值(在每个循环结束时)在整个计算过程中都是二项式系数。如果您要以另一种顺序计算乘积和除法,则很可能得到非整数,因此由于约定 int/int -> int,计算将失败,路径为整数变量类型。该博客没有提及这一点并不是很有帮助。

【讨论】:

  • 我不明白减号,因为我想模仿 (n-k+i)/i 我需要使用加号而不是减号,如下所示:@ 987654322@
  • n-k+i 表示 (n-k) + i,而不是 n - (k+i) :在通常的数学/和/编程中,减号运算符优先于加号运算符
猜你喜欢
  • 1970-01-01
  • 2014-10-22
  • 1970-01-01
  • 2015-09-13
  • 2016-02-09
  • 2014-06-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多