为什么这两个片段产生不同的结果?

时间:2013-08-21 23:29:58

标签: c++ ruby

理论上,这两个代码块应该用两种不同语言实现相同的功能。但它们会产生完全不同的输出。 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

Ruby输出:72900000000000000000

C ++输出:378158756814587

有谁知道为什么会这样?

修改

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

2 个答案:

答案 0 :(得分:1)

我弄明白了这个问题。这是我的ruby代码中的错误。

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

如果要打印MEMO[0]MEMO[1]的对象ID,您会发现它们完全相同。我假设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}}}

它完美无缺。

答案 1 :(得分:0)

我知道这不是你问题的答案,但是......如果你用第一行代替:

MEMO = Array.new(10) {Array.new(10) {Array.new(21) {0}}}
一切正常。两个阵列看起来都是一样的,对我来说它们之间没有区别,但似乎有一点差别导致你的问题。有什么想法吗?