【问题标题】:Why the algorithm gives different answers for C++ and Python?为什么算法对 C++ 和 Python 给出不同的答案?
【发布时间】:2020-12-31 02:29:43
【问题描述】:

我今天做了一个算法练习。这个问题的教程给出了一个用 C++ 编写的示例答案:

int dp[21][200];
int i, j, k;
 
void main()
{
    int bucketN, fishN;
    scanf("%d %d", &bucketN, &fishN);
 
    dp[0][0] = 1;  
 
    for(int i = 1; i <= bucketN; ++i) 
    {
        for(int j = 0; j <= fishN; ++j)
        {
            for(int k = 0; k <= 10 && j-k >= 0; ++k)
            {
                dp[i][j] += dp[i-1][j-k];
            }
        }
    }
    printf("%d\n",dp[bucketN][fishN]);
}

如果bucketNfishN 都是20,则输出将是65649764

我将C++实现翻译成Python,我的代码如下所示。

import numpy as np
arr = np.zeros((21, 200))

def main(bucket, fish):

    b, f = bucket, fish
    arr[0, 0] = 1

    for i in range(1, b+1):
        for j in range(f+1):
            for k in range(11):
                if j-k < 0:
                    break
                else:
                    arr[i, j] += arr[i-1, j-k]
    
    print(arr[b, f])
    return arr[b, f]

if __name__ == '__main__':
    main(20, 20)

bucketfish 仍然是 20,但输出是 68785126410.0

我感到很困惑,我认为我的代码和原来的 C++ 代码是一样的。希望有C++或者Python方面的高手给解释一下。

【问题讨论】:

  • 您能否打印出整个数组以查看数字开始不一致的位置,或者差异中是否存在明显的模式?
  • Python 代码给出了准确的答案,但 C 代码溢出了数据类型。
  • 将 C 代码中的数组声明更改为 long long 而不是 int,然后是 %lld 而不是 %d 以打印正确的值。另外,不知道你为什么认为那是 C++。
  • @ggorlen "Python 代码给出了准确的答案" - 它给出了答案。 “准确”不起作用。
  • @TedLyngmo 你是什么意思?

标签: python c++ algorithm


【解决方案1】:

在 C++ 代码中,dp 数组的数据类型是 int,最多可以容纳数字 2147483647。您正在寻找的真正的非溢出答案由您的 python 代码 68785126410 返回。更改中的第一行您的 C++ 代码来自: int dp[21][200];long long int dp[21][200]; 以及从 "%d%lld 的 printf 格式说明符,以查看 C++ 和 Python 中匹配(和正确)的答案

【讨论】:

  • 有趣的事实:它实际上比你描述的更糟糕更奇怪。 int 可能最多只能容纳 32767。它可能会容纳数亿。仅指定了 int 的最小大小,即 16 位。只要它不大于long,实现者就可以让它比它更大的任何东西。它甚至可以和long 一样大小。我见过所有整数类型大小相同的系统。
  • 别忘了int mainreturn 0;#include &lt;cstdio&gt;!这就是我们正在谈论的 C++。 (虽然我不确定为什么选择 cstdio 而不是 iostream。)
  • int64_t 通常是比long long 更好的选择,因为它的大小是已知的,因此您可以更轻松地确定它是否足够大以进行计算。尽管在实践中,long long 在所有现代编译器上都是 64 位的。如果您不需要负数(您的问题看起来就是这种情况),uint64_t 会给您额外的一点。
  • 使用 ubsan 运行 C/C++ 代码也可以极大地帮助发现问题,包括有符号整数溢出。
猜你喜欢
  • 2014-02-24
  • 2016-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多