数あるshuffle法の中で最も分かりやすいかつ速度が安定している
Fisher-Yatesアルゴリズムで値をごちゃまぜにしてみました。
どこまで値を増やしてもO(n)のままなので、速度にこだわらない
のであれば大体これ一択という流れになります。
こちらは、15個の値を順に並べ、シャッフルボタンを
押すと1から順に並んだ値とランダムで出した値を100通り
shuffleしています。
このやり方、先週ブログでも書いた文字列を判定する方法と
似ていますね。これを更に応用してランダムに1番から15番の値を
iが100に達するまで回しています。
100のところは500でも1000でもその限度まで回してくれるので
もっと回したい!というかたはお好みで。
<pre>public class MainActivity extends AppCompatActivity { int[] data = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; int[] first = new int[5]; int[] sec = new int[5]; int[] drawableIds; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.inject(this); //drawableIds = new int[typedArray.length()]; } @OnClick(R.id.shuffle) public void shuffle() { Random rand = new Random(); for(int i = 0; i < 100; i++){ for(int j =0; j < data.length; j++) { int temp; int num = rand.nextInt(data.length); temp = data[j]; data[j] = data[num]; data[num] = temp; } } } }</pre>
更に、このままだとシャッフルしただけで何も面白くないという
ことなので、せっかくなのでカードゲームのように最初の列から
値を5個ずつ取ってみましょう。
まず、一番最初にfirstという配列にドローした値を格納しています。
このfirstはもういじることはないので、次に連続して引きたい時に
先ほど引いた5個の値を後ろに押し戻して次の5個の値を
取り出します。
同時に10列目の値群も動かさないといけないので5の倍数で
動かしていきます。
一通り入れ替えたらSystem.out.printlnをして確認してみましょう。
こちらが確認できれば組立終了です。
@OnClick(R.id.take) public void draw() { for(int d = 0; d < data.length / 3; d++){ first[d] = data[d]; } System.out.println(Arrays.toString(first)); for(int s = 0; s < data.length / 3; s++){ int temp; temp = data[s]; data[s] = data[s+5]; data[s+5] = data[s+10]; data[s+10] = temp; } System.out.println(Arrays.toString(data)); }
シャッフルクラスの説明は以上でおしまいです。
これを一つのクラスにまとめればトランプとかボウズめくりの
ための汎用クラスとして使えそうですね。