• ベストアンサー

1から20までの整数から、重複なくランダムに3つ数づつを取り出す

1から20までの整数から、重複なくランダムに3つの数を取り出したいんですけど、簡単に出来るのでしょうか ?

質問者が選んだベストアンサー

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.5

高級言語は配列のランダム機能があったり するのでみなさんローレベルのランダム化 にはなれていないのでしょうか? 残念ながらみなさんのコーディングには 問題があります。 重複したら、リトライするという方式は 一番してはいけない方法です。 1000個の要素から1000個抜き出すときに、 999番目の要素は約0.1%の確率でしか重複 しない数値がヒットしません。 要素数が増えると加速度的に時間のかかる プログラムです。 また#4さんのように、適当な回数要素数 の中で入れ替えをするというの、よさそうに 見えますが、初期要素からいれかわらない 可能性が強く、かなり偏りがでるランダム です。 そもそも3つの要素を抜き出すのであれば ランダム処理は3回やればじゅうぶんのはずです。 以下の例はざっとかいたものなのでバグがある かもしれませんがランダム化のフローを 理解いただく参考までに。 <script language="javascript"> function rndview(min,max,num){ var a=new Array(); for (var i=min;i<=max;i++){ a[i]=i; } for (var i=min;i<=(min+num-1);i++){ var p1 = i+Math.floor(Math.random() * (max-i+1)); var p2 = a[i]; a[i]=a[p1]; a[p1]=p2; } txt=""; for (var i=min;i<=(min+num-1);i++){ txt+=(txt=="")?a[i]:","+a[i]; } alert(txt); } </script> <input type="button" value="ランダム" onClick="rndview(1,20,3)">

その他の回答 (12)

noname#17489
noname#17489
回答No.13

ソートが重いならこちらをどうぞ。 配列から既に選択した要素を取り除きながらランダムに選んでいく方法です。 ただ、10000個のとかから選ぶとなると要素数10000個の配列を用意しなければなりませんが。 function rnd_sel(min,max,num) {  var arr = new Array();  var results = new Array(num);  for (var i=0;i<max-min+1;i++) arr[i]=i+min;  for (var i=0;i<num;i++) {   var rnd = Math.floor((max-min+1-i)*Math.random());   results[i] = arr[rnd];   var tmp = arr[max-min-i]; //last   if (rnd!=(max-min-i)) arr[rnd] = tmp;  }  return results; } //インデントは全角スペースなのでご注意を...

  • UKY
  • ベストアンサー率50% (604/1207)
回答No.12

No. 9 の、比較関数でランダムな比較結果を返すというのはアイデアとしてはいいと思いますけど、sort メソッドの仕様としては比較関数が 'a consistent comparison function' でない場合の動作は 'implementation-defined' だから、やっぱりまずいと思います。 確かに主要なブラウザではエラーは出ないようですが、仕様上エラーが出ないという保証はないわけですし。 (ところで、単にランダムな比較結果を返すだけならわざわざ 100 倍して引かなくても function() { return Math.random() - 0.5; } で十分だと思います)

回答No.11

IE,NN,FFで確認してますがエラーは出ないはずです。 それとも、sort(-1.3...)とか直接値を代入した場合の話ですか? それはエラーになりますよw sortには比較式 return (b - a); など比較関数で 負数~0~正数の範囲でソート順序を返すようにします。 あとはご自分でお調べ下さい・・ .

  • B-Happy
  • ベストアンサー率0% (0/1)
回答No.10

横からすいません。 arr.sort(function(){return Math.random()*100 - Math.random()*100;}); って、どういうことなのでしょうか。 sort(-1.3...)とかだと、もちろんエラーになってしまうのですが。

回答No.9

シャッフルの手法としては不完全なんですが この程度のケースなら充分かと思います。 <script language="javascript"> arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; arr.sort(function(){return Math.random()*100 - Math.random()*100;}); document.write(arr[0]+","+arr[1]+","+arr[2]); </script> .

noname#19175
noname#19175
回答No.8

http://otd8.jbbs.livedoor.jp/javascript/bbs_tree?base=15264&range=1 内容が似てますが、、、? あちらのBBSでは、回答はつきそうにないですけどね。 方法は何種類かありますが、どの方法が良いか、というのは状況次第じゃないでしょうか? >重複したら、リトライするという方式は一番してはいけない方法です。 基本的にはそうなんですが、分母がとてつもなく大きく、取り出したい数(分子)がごく小さな場合は、 重複したらリトライの方が早いことがあります。 (重複確認の方法によっては、とてつもなく遅くなります) http://itmedia.okwave.jp/kotaeru.php3?q=2037528 ちょっと、こういう疑問がありますので、このBBSでの回答は控えさせて頂きます。 (アルゴリズム自体は一般的ですが、、、) 1つの方法として、参考URLを見てください。

参考URL:
http://www.openspc2.org/reibun/javascript/form_textarea/015/
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.7

>高級言語は配列のランダム機能があったりするのでみなさんローレベルのランダム化にはなれていないのでしょうか? >残念ながらみなさんのコーディングには問題があります。 >重複したら、リトライするという方式は一番してはいけない方法です。 >1000個の要素から1000個抜き出すときに、999番目の要素は約0.1%の確率でしか重複しない数値がヒットしません。 >要素数が増えると加速度的に時間のかかるプログラムです。 もちろんおっしゃることは、わかります、 #3のプログラムについて言えば、ある範囲の中から範囲に比べて少ない数が選ばれるということを想定したものです。 例えば、 1~10000(あるいはもっと大きい?)までの範囲の数の中から、3コ数を選びたいだけなのに、いちいちその範囲の数を重複させないためだけに候補を作るのは、いかにもムダです。 逆に、範囲のほとんど全数が必要になるなら、#3は、向かないのはおっしゃる通りですね。 そういったことは、ケースバイケースのように思われます。 #4については、いちいち評を挟みませんでしたが、#5でおっしゃる通りでかなり高コストだなあと思っていました。

  • don_go
  • ベストアンサー率31% (336/1059)
回答No.6

1~20までの値と乱数の結果を入れる為の配列テーブルを用意して 1~20までの数値と乱数値をセットした後、乱数テーブルの値を用いて ソートすれば求める結果が得られると思いますが?

回答No.4

少し違う考え方を書いておきます。 トランプと同じようなものだと考えて、20要素の整数を入れておく配列を作り、そこに1から20までの数値を入れておきます。それから乱数で0~19までの値を2つ作り、その値が違っていたらそれに対応する配列の位置の値を入れ換えます。これはトランプのシャッフルのようなイメージです。なので回数が多ければ多いほど順序がバラバラになります。で、十分にシャッフルしたら先頭の3つの値を残してあとは全部捨てれば終りです。 例) ボタンを押すたびに1~20の整数が重複なくランダムに3つカンマ区切りでテキストエリアに出て来ます。 <html> <head> <title>Random Test</title> <script language="JavaScript"> <!-- function setrand() { var max = 20; var a = new Array(max); var i; for (i = 0; i < max; i++) a[i] = i + 1; for (i = 0; i < 100; i++) { var p1 = Math.floor(Math.random() * max); var p2 = Math.floor(Math.random() * max); if (p1 != p2) { var tmp = a[p1]; a[p1] = a[p2]; a[p2] = tmp; } } document.f.t.value = a[0] + "," + a[1] + "," + a[2]; } // --> </script> </head> <body> <form name="f"> <input type="button" value="PushMe" onClick="setrand()"> <input type="text" name="t"> </form> </body> </html>

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

//配列=randomInt(範囲の下限, 範囲の上限, 個数) function randomInt(startRange, endRange, num){ if(endRange-startRange+1<num){//ムリ return []; } var a = new Array(); var c = 0; while(c < num){ var r = Math.round((endRange-startRange)*Math.random()+startRange); if(a[r]==undefined){//まだ無い a[r]=r; c++; } } var ret = new Array(); c=0; for(var x in a){//整理 ret[c++]=x; } return ret; } var rand3; //10~20までの範囲の重複しない3つの数の配列:randomInt(10, 20, 3) rand3=randomInt(10, 20, 3); alert(rand3.join(",")); for(i=0;i<rand3.length;i++){ alert(rand3[i]); }

関連するQ&A

  • 【エクセル】ランダムで重複しない整数を出したい。

    Windows 7、エクセル2007です。 ランダムで重複しない整数を任意の範囲から一部のみ入力するにはどうしたら良いでしょうか? 1.任意の範囲「1~50」とか「1~100」とか「15~300」とかから、20個だけとか40個だけとか。 2.ランダムなので「2,6,3,4,8,1・・・」とかのn、n+1、n+2ではないランダムな整数。 3.重複しないこと。 上記1~3を満たしたやり方ってありますか? 出てこない数があっても良いんです。 例えば、1~10までの範囲でランダムに3個だけセルに入力したいとき。 A1に7、A2に4、A3に9というふうに。 それが1~300の範囲で50個の数字をランダムに重複しないように入力する。 A1に15、A2に163、A3に92、・・・A50に43。 残りの250個の数字は入力されないという感じです。 乱数だと重複します。 ランク(順位)と組み合わせると、連続(n、n+1、n+2)になってしまいます。 列はどこでも良いんですが、行は連続したいです。 A1~A50とか、A1~A300とか。 関数の組み合わせでできないでしょうか? また、マクロは分からないので、詳しく解説して頂けると助かります! 情報が不足する点がありましたら指摘して下さい。 追加します。

  • Excelで整数ランダムにだすには

    Excelで整数ランダムにだすにはどのようにすればいいのでしょうか? 整数 1~50 同じ整数を重複しない よろしくお願いします。

  • Excelでランダムかつ重複無し整数の出し方

    例えば3~7の範囲で、ランダムかつ重複しないように整数を出したい場合、 どうしたらよいでしょうか? Windows XP Excel 2003です。

  • エクセルで重複しないランダムな1桁の数

    似たような質問はたくさんあるのですが,どれも今ひとつしっくりこないのであらためて質問します。 エクセルでA1:I1の範囲に1から9の数を重複なしでランダムに表示させたいのですが,よい方法を教えてください。(九九の練習プリント作成のためです。) 現在の知識で=TRUNC(RAND()*9)+1 とすることによって1から9までの整数値をランダムに表示することはできているのですが,これだけだと重複してしまいます。これを修正していただけると助かりますが,別の方法でもかまいません。 よろしくお願いします。

  • PHPで変数を重複しないようにランダムで配置したい

    表題のとおりなのですが、書きソースを見てもらえればわかりやすいかと思いますので、まずはご一読頂けると幸いです。 -------------------------------------------------------------------------------- <?php $rank[1] = "<td>100個</td>"; $rank[2] = "<td>200匹</td>"; $rank[3] = "<td>300万</td>"; $rank[4] = "<td>400億</td>"; $rank[5] = "<td>500台</td>"; ?> <table>  <tr>   <?php echo $rank[ここに重複しないランダムな整数を入れたい]; ?>   <?php echo $rank[ここに重複しないランダムな整数を入れたい]; ?>   <?php echo $rank[ここに重複しないランダムな整数を入れたい]; ?>  </tr>  <tr>   <?php echo $rank[ここに重複しないランダムな整数を入れたい]; ?>   <?php echo $rank[ここに重複しないランダムな整数を入れたい]; ?>  </tr> </table> -------------------------------------------------------------------------------- このような形で、 [] の中の数字を重複せずにランダムに入力されるようにしたいです。 目的としてはテーブルの中の要素をページを更新するたびにランダムに並べ替えるためです。 私が思いついた方法は上記のようなものが一番シンプルで良い気がしたのですが、ほかにスマートな方法がありましたら、是非教えていただきたいです。 サンプルでは変数の中にちょっとしたものしか入っていませんが、実際にはもっと長いものになります。 どうかよろしくお願い致します。

    • ベストアンサー
    • PHP
  • Excel 文字や記号を重複無し&ランダムで出す

    以前、整数をランダムかつ重複しないように出す方法を質問しました。 http://okwave.jp/qa/q8998274.html 今度は、文字や記号などの整数以外のものをランダムかつ重複しないように出したいのですが… 可能でしょうか?

  • 重複しない整数をランダム表示

    エクセル98を使用しています。 例えば3つのセルに1~5の数字をランダムに、重複させないように表示させることはできるでしょうか? 作業用のスペースを使用して、いくつか処理を加えれば可能なのですが、関数を組み合わせてもっとスマートにできる方法はないかと思い、ダメ元で質問させて頂きました。 大したことではないのですが、いいアイディアがある方はアドバイスを頂けると助かります。

  • 整数のランダム生成について

    エクセル98を使用しています。 例えば1~5の数字の整数をランダムに発生させようとしているのですが、 =INT(RAND()*5+1) と記述する方法と =INT(RAND()*5)+1 と記述する方法があるのですが、どちらが良いのでしょう? 実際試したみたところ、どちらも1~5の整数をランダムに発生させることができています。 結局は同じ意味なのでしょうか? 大したことではないのですが、よろしくお願いします。

  • Excelでのランダムな整数の出し方

    A1のセルに、ルーレットのようにランダムな整数を 表示させたい時は、 =INT(RAND()*10) という関数を使うのだと思いますが、 これだと0~9までが均等に出現しますよね。 A1には、0,1,2の3つのみを ランダムに出現させたい、という場合は どのように設定すればいいのでしょうか? 宜しくお願いします。

  • ランダム数の発生

    エクセル上でランダム数を発生させるソフトをご存じないでしょうか? できれば、整数桁4桁くらいまで、小数点以下4桁くらいまでを指定して(桁数を指定して)できるとよいのですが・・・。