Flash Pro CS5
AS3.0
で記述しています。
1~10の整数をランダムかつ重複せずに配列に格納したいと考えています。
そこで,ネット上で参考になるソースを見つけ,
以下のように書き直しました。
var int_a = new Array();
var int_b = new Array();
function RandomInt():void{
//ここだけ変更すればよい
var maxN:Number = 10;//乱数の最大値
//0~maxNの数字を全部配列に入れる
for (var i:int=0; i< maxN; i++) {
int_a[i] = i+1;
}
var j:Number = 0;
var a_length:Number = int_a.length;
//要は配列をシャッフルする
while (a_length) {
var int_r:Number = Math.floor(Math.random()*(maxN+1-j));
//乱発生した整数を配列int_bに順番に入れ、int_aから削除する
int_b[j] = int_a.splice(int_r, 1);
j++;
//配列int_a内の数字が一つずつ減っていく
a_length = int_a.length;
}
//ここで配列int_bがシャッフルされた
trace(int_b);
}
RandomInt();
としました。
しかし出力結果がなぜか
8,2,4,9,,7,6,5,10,3,1のように抜けている部分があり,
次のフレームで
for(var j:int=1; j <= 10; j++){
trace(int_b[j]);
}
として確認してもやはり
2
4
9
7
6
5
10
3
1
となってしまします。
どの部分がおかしいのか教えていただきたいです。
また,乱数発生の部分で
Math.floor(Math.random()*(maxN+1-j));
という風に記述してあったのですが,ここは間違いではないのでしょうか?
jを引いていくと発生する乱数の範囲が徐々に狭くなっていってしまうと思ったのですが;
それとも元のソースコードを使って
ttp://www.renowan.com/blog/?p=143
0~9までの乱数を発生させてそれぞれに1を足す方が簡単でしょうか?
よろしくお願いします。
No.1ベストアンサー
- 回答日時:
その式ですと、乱数の範囲が、配列変数のインデックス(管理番号)の最大値よりも 1 だけ広くなってしまいます。
RandomInt 関数内の乱数を求める式を
Math.floor( Math.random() * ( maxN - j ) );
に、変更してみてください。
たった 1 の違いが、何が問題なのかと言いますと。
ご提示の式ですと、0 ~ 配列変数の要素の総数、の範囲で乱数を求めることになります。
例えば int_a が 10 個の要素を持っている時、0 ~ 10 までの乱数を求めてランダムに要素を1つ取るとすると、最大の 10 が出た時には int_a[ 10 ] を取ることになります。
しかし、配列変数のインデックスは 0 から始まるので int_a は 0 から 9 番までしかなく、10 番を指定したのでは値の取得に失敗してしまいます。
関数内で、乱数で選んだインデックス(変数 int_r )と int_a の要素の総数を表す a_length の値を監視してみると分かるのですが、値の取得に失敗して「 ,, 」と歯抜けになるのは乱数(= int_r )と a_length が同じになった場合で、運よく1度も同じにならなかった時はこの問題は起こりません。
- - - - -
Math.random で任意の範囲の乱数を発生させる式が、Adobe 社のホームページで紹介されています。
・Math.random() でランダムな整数を取得する方法
http://kb2.adobe.com/jp/cps/228/228622.html
ご参考になさった作例では、この式を利用して配列変数 int_a のインデックスの範囲内で乱数を決めて任意の要素を1つ抜き取り、それを別の配列変数 int_b の先頭から順に詰めていく、といった方法をとっていると思われます。
int_a の要素は最初は変数 maxN と同じ数、ご提示のスクリプトですと 10 個あるのですが、配列変数のインデックスは 0 から始まるので、最後の要素は int_a[ 9 ] です。
ですから、抜き取る要素を決める乱数は 0 ~ 9 の範囲で求めます。最大値の 9 とは、maxN - 1 のことです。
すると、先の式に当てはめますと、
Math.floor( Math.random() * ( ( maxN - 1 ) - 0 + 1 ) ) + 0
これを整理しますと、
Math.floor( Math.random() * maxN );
になります。
int_a から splice メソッドで要素を抜き取ると配列変数の要素が少なくなっていきますから、要素が減った分だけ乱数の範囲も狭めていかなければなりません。
抜き取ってなくなった数は、値を抜き取った時にカウントを取っている変数 j を見ると分かります。
合わせますと、int_a の 0 ~最大インデックスの間で乱数を求める式は
Math.floor( Math.random() * ( maxN - j ) );
となります。
* * *
今回の件での変数 maxN とは、初期状態の int_a の要素の総数と同じ意味です。
配列変数の要素の総数は length プロパティに記録されており、要素を削除・追加した時には length プロパティは自動的に修正されます。
この点を利用して、
(↓ 各行頭に全角のスペースが入っています。コピーする際はご注意ください)
//***
//抜き取った値をint_bに詰める時のインデックス
var j:Number = 0;
//int_aの要素が尽きるまでループ
while( int_a.length )
{
//抜き取る要素をランダムに選ぶ
var int_r:Number = Math.floor( Math.random() * int_a.length );
//int_aの要素を抜き取り、int_bの先頭から詰めていく
int_b[ j ] = int_a.splice( int_r , 1 );
//値を詰めるインデックスを更新
j++;
}
//***
と、書くこともできます。
なお、繰り返しますが、配列変数のインデックスは”0 から”始まり、最後は”要素の総数 - 1 ”です。
配列変数 int_b の値を for ループで全部取り出す時は、
for( i = 0 ; i < int_b.length ; i++ )
というように書きます。
先頭は1番ではありませんので、ご注意ください。
丁寧でわかりやすい解説ありがとうございました。
別の書きかたでのコードも大変参考になりました。
for( i = 0 ; i < int_b.length ; i++ )
の部分ですが,どうしても配列の0番目からではなく1番目~10番目に格納したかったので
そのように記述してしまいました。
しかし0~9番目に入れて後で新しい配列に入れなおせばよかったのですね。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# 10人分の生徒の英語の点数{32,34,41,38,40,26,14,46,42,50} と数学の点 2 2022/05/26 21:31
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
arduino プログラムについて
-
uwscでExcelに自動記入
-
Python でシャットダウンのコマ...
-
flash (.swf) を編集したい
-
Giam
-
laptop go2からの買い替え、lap...
-
私のコンピューター上のファイ...
-
Flashコンテンツを使ったWebサイト
-
Flashをブロックしないで
-
Adobe Flash Player
-
Windows10重い
-
パソコンのリカバリーについて
-
ロック画面に天気を表示したい
-
Adobe(マクロメディア)のFLAS...
-
adobe flash playerは無料です...
-
自分でチラシを作りたいです!...
-
ヘッダーデザインをするさい形...
-
FLASH MX で作成した、flashやA...
-
この曲のタイトルを教えてください
-
Flash MXで作成したフラッシュ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VB.NET の配列の要素数
-
変な質問ですみません、n番目の...
-
配列の要素番号を取得するには?
-
VBでボタンを押すと画像をラン...
-
Vba 配列の中の特定文字列の位...
-
DataGridでCTRLキーを押さずに...
-
IDの自動採番について
-
複数の変数宣言を、for文で一気...
-
VB6 複数行のテキストをリスト...
-
重複しない乱数の生成
-
重複しない乱数整数を発生させる。
-
C言語のsizeof(サイズオブ)演算...
-
入れ替える処理
-
絵を描き、その都度のxy座標を...
-
正規表現でタグの中身を抜き取...
-
2次元配列 ソート
-
Action Script 2.0 配列の比較
-
画像をランダムに表示するには
-
ランダムに数字を並び変える方法は
-
景品パネルの作り方
おすすめ情報