2

这两个代码块理论上应该做同样的事情,只是用两种不同的语言实现。但它们产生完全不同的输出。C++ 产生了预期的结果,而 ruby​​ 输出甚至没有接近。

C++

unsigned long MEMO[10][10][21];

long generate(int a, int b, int l){
    if(MEMO[a][b][l] != 0){
        return MEMO[a][b][l];
    }
    if(l==0){
        return 1;
    }
    for(int i =0; i<=9-a-b; i++){
        MEMO[a][b][l] += generate(b, i, l-1);
    }
    return MEMO[a][b][l];
}

int main(){
    unsigned long sum = 0L;
    for(int i=1; i<10; i++){
        sum += generate(0,i,19);
    }
    printf ("Answer: %lu\n",sum);
    return 0;
}

红宝石

MEMO = Array.new(10, Array.new(10, Array.new(21, 0)))

def generate a, b, l
  if MEMO[a][b][l] != 0
    return MEMO[a][b][l]
  end

  if (l==0)
    return 1
  end

  0.upto(9-a-b).each do |i|
    MEMO[a][b][l] += generate(b, i, l-1)
  end

  MEMO[a][b][l]
end

sum = 0
1.upto(9).each do |i|
    sum+= generate(0, i, 19)
end

puts sum

红宝石输出:72900000000000000000

C++ 输出:378158756814587

有谁知道这可能是为什么?

编辑

以防万一这不清楚, 378158756814587 是我想要的答案,这是我期望 ruby​​ 代码产生的。它不是 C++ 端的整数溢出。378158756814587 仍然是使用unsigned long long.

4

2 回答 2

1

我解决了这个问题。这是我的 ruby​​ 代码中的错误。

MEMO = Array.new(10, Array.new(10, Array.new(21, 0)))

如果您要打印出对象 ID,MEMO[0]MEMO[1]会发现它们完全相同。我假设Array.new(10, Array.new)会在其中创建一个Array包含 10 个不同Array对象的对象。相反,它会创建Array对同一Array对象的 10 个引用。通过将第一行更改为以下内容:

MEMO = Array.new
10.times do
  MEMO << Array.new
  10.times do
    MEMO[-1] << Array.new(21, 0)
  end
end

甚至更简单

MEMO = Array.new(10) {Array.new(10) {Array.new(21) {0}}}

它工作得很好。

于 2013-08-22T00:37:32.277 回答
0

我知道这不能完全回答您的问题,但是...如果您将第一行替换为:

MEMO = Array.new(10) {Array.new(10) {Array.new(21) {0}}}

一切正常。两个数组看起来都一样,对我来说它们之间没有区别,但似乎有一些小的差异会导致你的问题。有任何想法吗?

于 2013-08-22T00:36:28.913 回答