連続しない乱数を取得
一般的に、乱数を取得するにはRandomクラスを用います。
例えば0~9までの乱数を取得したいなら、
Random r = new Random(); randInt = r.nextInt(10);
となり、単純です。
ちなみ、4、5,6,7,8から選びたいときは、r.nextInt(5)+4とします
ただし、このコードで取得する乱数は前後の数値を考慮することはなく独立したものです。
返す値を並べてみると、、
6,2,3,2,7,1,7,3,3,7,6,3,6,7,1,6,0,8,3,8,7,6,2,1,5,8,1,2,0,2,2,
8,0,8,2,8,9,1,8,5,6,2,2,0,1,0,1,4,4,7,2,3,3,3,6,5,6,5,3,3,7,8,
1,2,3,5,9,9,9,5,0,5,9,4,4,
といったようになり、同じ数値が連続することがあります。
単に乱数を発生させたいだけなら問題ありませんが、連続させたくない場合もあります。
ではどうしたらよいでしょうか。
発生させる数値の前の数値と同じであったら、再度乱数を取得する。ということにまります。
再帰で実現
ここで使う手法が、いわゆる、再帰です。
以下のように書き換えてみます。
このコードは前の2つの数値とは違う乱数を取得します。1,1,1や1,0,1、0,1,1といった結果を返しません。
private int getRandInt(int num1,int num2, int limit){ Random rnd = new Random(); int R = rnd.nextInt(limit); if(R == num1 || R == num2){ return getRandInt(num1,num2,limit); }else{ return R; } }
num1,num2の数値のいずれかに一致する場合は再度実行させ、一致しなければその値で決定です。
これで0からlimitまでの数値の中でnum1,num2以外の乱数を取得できます。
再帰は理屈では理解しにくいので感覚的に理解するとわかりやすいでしょう。
連続しない乱数を取得するソースコード
ではコードを書いてみましょう
300ミリ秒ごとに乱数を取得して表示します。
public class MainActivity extends AppCompatActivity { Timer mTimer = new Timer(); TimerTask mTimerTask = new MainTimerTask(); Handler mHandler = new Handler(); int randInt; int rand1 = -1; int rand2 = -1; String result=""; public class MainTimerTask extends TimerTask { @Override public void run() { mHandler.post(new Runnable() { @Override public void run() { try { print(); }catch (Exception e){ } } }); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTimer.scheduleAtFixedRate(mTimerTask, 0, 300); } private void print(){ randInt = getRandInt(rand1,rand2,10); rand1 = rand2; rand2 = randInt; result = result+randInt+","; Log.d("Log0",""+result); } private int getRandInt(int num1,int num2, int limit){ Random rnd = new Random(); int R = rnd.nextInt(limit); if(R == num1 || R == num2){ return getRandInt(num1,num2,limit); }else{ return R; } } }
となります。途中の結果も、
2,4,9,8,0,9,1,0,7,9,3,6,1,0,9,5,8,4,0,8,9,7,5,4,8,0,5,3,4,5,3,2,
1,3,2,6,9,8,6,2,8,9,4,8,2,6,9,8,3,9,8,2,0,6,1,9,5,2,7,8,0,3,1,6,
3,5,2,7,4,3,1,6,0,8,7,3,0,9,4,6,1,2,7,4,8,9,1,5,6,8,1,6,2,9,3,5,
2,3,6,0,9,2,3
となり、連続しませんね。