プロが教える店舗&オフィスのセキュリティ対策術

題のとおり、javascriptで重複しないように値を取得したいと思っております。

以下ソースの一部です。
for (var v = 0; v < 5; v++) {
var i = 0;

var a = Math.floor(Math.random()*test.length);


while ( a == i ){
a = Math.floor(Math.random()*test.length);
}

if (a != i){
i = a;
}

}
このプログラムだと隣り合う回数の1回目と2回目などは重複しないんですが、1回目と3回目は重複してしまいます。
なにか重複しない方法はないでしょうか?初心者説明ですいませんが、ご教授おねがいします。

A 回答 (1件)

重複しない乱数を発生させるためには、


1.乱数候補(0,1,2,3など)を配列に格納
2.配列をシャッフル
3.配列から順番に取り出す
の様な手段をとる必要があります。

以下にサンプルコードを載せておきます。
最初にシャッフルするのではなく
乱数が取り出されるたびに少しずつシャッフルする感じにしてみました。
(this.arr[idx]=this.arr[this.cnt-1];の部分がシャッフルに相当。
本当のシャッフルなら値の交換が必要ですが、乱数生成のためだけなら必要ないです。)

----------------------------------------------------------------------
//once_rand: min以上max未満の重複しない乱数を生成するためのオブジェクト
function once_rand(min,max){
  this.cnt=max-min;
  this.arr=[];
  //乱数候補を配列に格納
  for(var i=0;i<this.cnt;i++){this.arr[i]=min++;}
}
//乱数を取り出すメソッド
once_rand.prototype.next=function(){
  if(this.cnt<=0){
    //もう乱数候補が残っていない
    return undefined;
  }
  //乱数を取り出す位置を決定
  var idx=Math.floor(Math.random()*(this.cnt));
  //乱数を取り出す
  var rand_val=this.arr[idx];
  //重複しないように最後尾の要素で上書き(今のthis.arr[this.cnt-1]は次回以降使われない)
  this.arr[idx]=this.arr[this.cnt-1];
  //残りの乱数候補が減少
  this.cnt--;
  return rand_val;
}

//テスト
var rand1 = new once_rand(1,15); //1以上15未満
var str=rand1.next();
while(1){
  var rand_val=rand1.next(); //乱数を取り出す
  if(rand_val == undefined){break;}
  str += ","+rand_val;
}
alert(str);
    • good
    • 0
この回答へのお礼

Wernerさんのやり方を参考に自分なりにプログラムをつくり、進むことが出来ました。ありがとうございました。

お礼日時:2007/12/10 04:16

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!