2

配列を並べ替えるメソッドを書きました (Ruby には並べ替え関数が付属していることは知っていますが、アルゴリズムを練習したかったのです)。本当に奇妙なエラーが発生しましたが、なぜこれが起こっているのかわかりません。

これが私のコードです:

def permute(arr)
  permutation(arr.sort)
end

def permutation(arr, result=[])
  k = nil
  result += [arr]
  (arr.length-1).times do |i|
    if arr[i] < arr[i+1]
      k = i
    end
  end
  if k.nil?
    return result
  else
    l = -1
    arr.length.times do |i|
      if arr[k] < arr[i]
        l = i
      end
      l = nil if l == -1
    end
    arr[k], arr[l] = arr[l], arr[k]
    arr = arr[0..k] + arr[k+1..-1].reverse
    return permutation(arr, result)
  end
end

メソッドは再帰的であり、メソッドがネストされた配列を返すようにするため、連続する呼び出しごとに変数に連結arrします。resultresult += [arr][[1, 2, 3], [1, 3, 2]..]

ただし、このメソッドを呼び出すと、まったく奇妙な結果が得られます。

permute([1,2,3])
=> [[1, 3, 2], [2, 3, 1], [2, 3, 1], [3, 2, 1], [3, 2, 1], [3, 2, 1]]

最後の 3 つの結果がすべて であるのはなぜ[3,2,1]ですか? また、他の配列も正しくありません。本当に奇妙なことは、連結を に変更することでこれを修正できることresult += arrです。この変更により、次のようになります。

permute([1,2,3])
=> [1, 2, 3, 1, 3, 2, 2, 1, 3, 2, 3, 1, 3, 1, 2, 3, 2, 1]

#I know that I can get my desired nested array like so, but that's beside the point
[1, 2, 3, 1, 3, 2, 2, 1, 3, 2, 3, 1, 3, 1, 2, 3, 2, 1].each_slice(3).to_a
=> [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

必要なネストされた配列を取得できませんが、出力では正しい順列が得られます。なぜ今は正しく動作しているのに、私が使用していたものではないのresult += [arr]ですか? これは Ruby のバグですか、それとも何か不足していますか?

4

1 に答える 1