-1

私は次のような未知の要素数を持つ複数の配列を持っています

a = []
a << [:a, :c, :e]
a << [:b, :f, :g, :h, :i, :j]
a << [:d]

結果は次のようになります〜(丸めなどによる詳細はあまり気にしません)

r = [:b, :a, :f, :g, :d, :c, :h, :i, :e, :j]

これが私ができると思う方法です

まず、各配列の要素を同じ長さに均等に拡張/分散する必要があるため、次のようになります。

a << [nil, :a, nil, :c, nil, :e]
a << [:b, :f, :g, :h, :i, :j]
a << [nil, nil, :d, nil, nil]

次に、通常どおりに インターリーブします

r = a.shift
a.each { |e| r = r.zip(e) }
r = r.flatten.compact

私の現在の問題は、これらの要素を配列全体に均等に(可能な限り)分散させる方法です。4つの要素を持つ1つの配列と、5つの要素を持つ他の配列が存在する可能性がありますが、おそらく最大のものが最初に配置されます。

もちろん、これを達成する他の方法があるかどうかを確認するといいでしょう:)

4

1 に答える 1

2

配列のサイズで割った要素インデックスの位置に基づいて、これを行うためにソートを使用し、さらに配列IDに基づいてオフセットを使用して、一貫性を維持します(一貫性が必要ない場合は、代わりに小さなランダムオフセットを使用できます) )。

a = [:a,:b]
b = [:c]
c = [:d,:e,:f]
d = [:g:,:h,:i,:j]

def sort_pos array, id
  (1..array.size).map { |i| (i - 0.5 + id/1000.0)/(array.size + 1e-6) }
end

# Combine all the arrays with their sort index, assigning ids to each array for consistency.
# Depending on how you receive these arrays, this structure can be built up programatically, 
# as long as you add an array plus its sort index numbers at the same time
combined = (a + b + c + d).zip( sort_pos(a, 1) +  sort_pos(b, 2) +  sort_pos(c, 3) +  sort_pos(d, 4) )


# Extract the values from the original arrays in their new order
combined.sort_by { |zipped| zipped[1] }.map { |zipped| zipped[0] }

=> [:g, :d, :a, :h, :e, :i, :b, :f, :j, :c]

Rubyでこれを行うためのよりクリーンな方法があるかもしれません。。。しかし、最終的な結果は、あなたが求めているもの、つまり複数のアレイの「均等な」組み合わせだと思います。

統計的な観点からミックスの均一性のみを気にする場合(つまり、時間の経過とともに「公平」である場合)、次のようにすることができます。

(a+b+c+d).shuffle

=> [:g, :b, :i, :c, :a, :h, :e, :j, :f, :d]
于 2013-03-26T14:08:39.387 に答える