質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

4回答

2715閲覧

かんたんなアルゴリズムのミス??ランダムな数を重ならないように配列に入れる

otftrough

総合スコア476

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2015/11/08 17:19

変数pNum[]にランダムな数を重ならないように入れたいのですが、なぜかうまくいきません。
多分この部分だと思うのですが、チェックしてもらえませんか?

javascript

1 Q_MAX = ans.length; 2 i = 0; 3 a = 0; 4 while(i < Q_MAX){ 5 qNum[i] = Math.floor(Math.random() * Q_MAX); 6 while(a < qNum.length - 1 && i > 0){ 7 if(qNum[i] == qNum[a]){ 8 i--; 9 a = 0; 10 break; 11 } 12 a++; 13 } 14 i++; 15 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

コードから類推するに 要素数 Q_MAX の配列に、0 ~ Q_MAX-1 までの数を重複しないように入れる、
ということですよね。

ならば、0 ~ Q_MAX-1 までの整数をランダムに並べ替える(シャッフルする)というロジックの方がいいと思います。
現状のロジックだと後に行くほど重複する確率が高くなり、再試行が多発します。

シャッフルのjQueryプラグインが下記にありますので、それを利用すると簡単です。

jQuery: Shuffle Plugin – Yelotofu

上記のプラグインをコピーしておいて、

javascript

1Q_MAX = ans.length; 2i = 0; 3for (i = 0; i < Q_MAX; i++) { 4 qNum[i] = i; 5} 6 7qNum = $.shuffle(qNum);

追記:jQueryタグがついてなかったので、jQueryなしで。

javascript

1//シャッフルメソッドを定義 2Array.prototype.shuffle = function() { 3 var i = this.length; 4 while (i) { 5 var j = Math.floor(Math.random()*i); 6 var t = this[--i]; 7 this[i] = this[j]; 8 this[j] = t; 9 } 10} 11 12var qNum = []; 13Q_MAX = 10; 14//0 ~ 9 までの連番の配列を生成 15for (i = 0; i < Q_MAX; i++) { 16 qNum[i] = i; 17} 18//配列をシャッフル 19qNum.shuffle();

上記のシャッフルメソッドはFisher–Yates shuffleという割と有名なアルゴリズムで偏りなく高速にシャッフルできます。

ちなみに、質問のコードの間違いは、aの初期化の位置ですね。重複チェックのループの前で初期化しないと。

while(i < Q_MAX){ qNum[i] = Math.floor(Math.random() * Q_MAX); a = 0; //ここで初期化 while(a < qNum.length - 1 && i > 0){ if(qNum[i] === qNum[a]){ i--; break; } a++; } i++; }

投稿2015/11/08 22:50

編集2015/11/09 12:11
hatena19

総合スコア33715

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

質問文のコードをベースにしたものを示します。

javascript

1var qNum = []; 2Q_MAX = 10; // qNum.length; 3 4var idx = 0; 5while (idx < Q_MAX) { 6 // 追加する数の候補 7 n = Math.floor(Math.random() * Q_MAX); 8 9 // 重複をチェックする。 10 var exists = false; 11 for (var a = 0; a < idx; a++) { 12 if (n == qNum[a]) { 13 exists = true; 14 break; 15 } 16 } 17 18 if (exists) { 19 // 値が重複していたので、値を選び直す。 20 continue; 21 } 22 23 // 値を登録する。 24 qNum[idx] = n; 25 idx++; 26} 27 28console.log(qNum);

実行例 (node.js で実行)

$ node 111.js [ 8, 3, 7, 0, 5, 1, 9, 4, 2, 6 ] $ node 111.js [ 6, 1, 7, 8, 3, 9, 5, 4, 2, 0 ]

投稿2015/11/09 13:16

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

質問を取り違えた様子ですので、削除

投稿2015/11/08 18:38

編集2015/11/08 18:44
daive

総合スコア2028

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

場当たりで書くんではなくて、こんな感じで、処理単位ごとに。

javascript

1function makeUniqArr(count) 2{ 3 var arr = []; 4 5 //重複を判定する 6 //重複があれば true を返す 7 var check_duplicate = function(arr, num) { 8 //処理 9 return false; 10 }; 11 12 // ランダムな数値を生成する 13 var mkRand = function() { 14 //処理 15 return int; 16 }; 17 18 //指定回数分ループ 19 for (var i = 0; i < count; i++) { 20 var num = mkRand(); 21 if (check_duplicate(arr, num)) { 22 i--; 23 } else { 24 arr[i] = num; 25 } 26 } 27 28 return arr; 29}

投稿2015/11/08 18:26

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otftrough

2015/11/09 01:19

見やすくなって、書きやすさも上がりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問