2

これら 2 つのコード ブロックは、理論的には、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

私は問題を理解しました。私のルビーコードのエラーです。

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

のオブジェクト ID を出力するMEMO[0]MEMO[1]、それらがまったく同じであることがわかります。私が想定していたのは、その中に 10 個の異なるオブジェクトを持つ をArray.new(10, Array.new)作成することです。代わりに、同じオブジェクトへの参照を 10 個作成します。最初の行を次のように変更します。ArrayArrayArrayArray

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 に答える