値の交換

並べ換え(sort)や、シャッフルの操作をするときに必須となってくるのが データの交換操作である。もっとも簡単な例として

x = 10
y = 20

となっているときに、xyの値を交換する プログラムを考えよう。単純に考えて、

x = y
y = x

としたら、これはうまくいかない。なぜなら、1行目のx=y により、すぐにxの値がy(20)になってしまい、 それまでxの持っていた10という値は消えてしまう。

このような場合は、作業用変数を作って、一度片方の値を保存してから入れ 換え作業をする必要がある。

w = x		# wが作業用変数
x = y
y = w		# wには以前のxの値が残っている

これをふまえて、配列(あるいはハッシュ)に保存されている i番目要素と、j番目要素を交換するプログラムは 次のようになる。

# arrが配列。arr[i] と arr[j] の値を交換する
w = arr[i]
arr[i] = arr[j]
arr[j] = w

配列のシャッフル

配列の要素をでたらめな順番に並べ換える(シャッフルする)には 乱数を生成する randメソッドを利用し、ランダムな位置にある 要素と値を交換して行けばよい。

  1. 0番目要素と ランダムな位置の要素を交換する
  2. 1番目要素と ランダムな位置の要素を交換する
  3. 2番目要素と ランダムな位置の要素を交換する
    :
    :
    以下同様
    :
    :
  1. 51番目要素と ランダムな位置の要素を交換する
  2. 52番目要素と ランダムな位置の要素を交換する

「ランダムな位置」は、配列の要素を超えてはならないから、 randメソッドに上限となる整数を指定する。

配列の添字を超えない乱数は rand(配列.length) によって生成できる。

以上の知識をふまえて、配列にある要素をシャッフルするメソッドは以下の ように書ける。

def shuffle(a)
  srand
  0.upto(a.length-1) do |i|
    j = rand(a.length)    # 交換相手をランダムに選ぶ
    w = a[i]
    a[i] = a[j]
    a[j] = w
  end
  a
end

本日の目次