OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

乱数について

  • すぐに回答を!
  • 質問No.213544
  • 閲覧数125
  • ありがとう数4
  • 気になる数0
  • 回答数4
  • コメント数0

お礼率 79% (107/134)

今、あるデータの順番をばらばらにするプログラムを作ろうとしています。

 たとえば、a,b,c,dとあったら、d,b,c,aとするように、この時考えられるプログラムは、データの数だけ配列を用意して、乱数で、どのデータを出力させるかを決定し、出力し終わったら、その配列のところに印を立てて、次にくるデータに対して、2重にならないように順次、出力していく方法が考えられるのですが。。。
 
 膨大なデータをこのように、すると、二重になる確立が出力するたびに、高くなっていって、なかなか終わらなくなってしまいます。

 そこで、残ったデータから、ランダムに選び出すアルゴリズムまたは、関数はないでしょうか?よろしくお願いします。
通報する
  • 回答数4
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

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

  • 回答No.1
レベル8

ベストアンサー率 51% (21/41)

データの数だけ配列を用意して、乱数で適当な回数、場所を入れ替えて
(シャフルして)から

先頭から順番に取れば?
お礼コメント
Nickee

お礼率 79% (107/134)

 なるほど!以外に単純でしたね。
ありがとうがございました。
投稿日時 - 2002-02-08 13:39:48
-PR-
-PR-

その他の回答 (全3件)

  • 回答No.2
レベル13

ベストアンサー率 24% (357/1463)

実データとは別に、それに対するインデックスまたはポインタの配列を作ります。 例えば  1 - a  2 - b  3 - c  4 - d という感じです。 乱数で、インデックスを選択し、対応するデータを出力します。 例えば上の例で3が選択されたらcです。 選択されたインデックスを取り除きます。すると  1 - a  2 - b  4 - d    cはインデックスなし となり ...続きを読む
実データとは別に、それに対するインデックスまたはポインタの配列を作ります。
例えば
 1 - a
 2 - b
 3 - c
 4 - d
という感じです。
乱数で、インデックスを選択し、対応するデータを出力します。
例えば上の例で3が選択されたらcです。
選択されたインデックスを取り除きます。すると
 1 - a
 2 - b
 4 - d
   cはインデックスなし
となります。
残ったインデックスから乱数で一つを選択し、インデックスが
無くなるまでこれを続けます。
お礼コメント
Nickee

お礼率 79% (107/134)

>残ったインデックスから乱数で一つを選択し

いや、その残ったインデックスから、どのように選択するのか知りたかったものですから。。乱数で選択すると、重なる部分が出てくるわけじゃないですか。そうすると、選択するたびに、重なる部分が多くなるので、処理速度が遅くなるので、残ったインデックスからどのように、乱数で選択するのかを聞きたかったのですが。。。

ご意見 ありがとうございました。
投稿日時 - 2002-02-08 13:44:29
  • 回答No.3

乱数の範囲を狭めていき、選択されたものを次に選択されない位置に移動させるようにします。 #define N 10 int a[N]; int i, r, t; for (i = 0; i < (N - 1); i++) { // i の位置から最後までの中で1つ選択 r = i + rand() % (N - i); // 選択したものを i の位置と交換する t = ...続きを読む
乱数の範囲を狭めていき、選択されたものを次に選択されない位置に移動させるようにします。

#define N 10
int a[N];
int i, r, t;

for (i = 0; i < (N - 1); i++)
{
// i の位置から最後までの中で1つ選択
r = i + rand() % (N - i);

// 選択したものを i の位置と交換する
t = a[i];
a[i] = a[r];
a[r] = t;
}

for (i = 0; i < N; i++)
{
出力(a[i]);
}
お礼コメント
Nickee

お礼率 79% (107/134)

ほ~
非常に勉強になりました。そういう方法もあるんですね。

ありがとうございました。
投稿日時 - 2002-02-08 13:50:20
  • 回答No.4
レベル14

ベストアンサー率 30% (2593/8599)

No.1の方の方式(仮にAとします)とNo.3の方の方式(仮にBとします)がよく使われます。 バッチ的な処理ではAが適しています。(前処理に時間がかかってもいいが、処理をはじめたら高速) 一方、リアルタイム処理ではBが適しています。(前処理がいらず、毎回一定時間で処理可能) 全部終わったら又、対象を広げて続けると言う場合、Aでは、又、シャッフルが必要ですが、Bでは対象範囲を広げるだけでいいので一瞬で ...続きを読む
No.1の方の方式(仮にAとします)とNo.3の方の方式(仮にBとします)がよく使われます。
バッチ的な処理ではAが適しています。(前処理に時間がかかってもいいが、処理をはじめたら高速)
一方、リアルタイム処理ではBが適しています。(前処理がいらず、毎回一定時間で処理可能)
全部終わったら又、対象を広げて続けると言う場合、Aでは、又、シャッフルが必要ですが、Bでは対象範囲を広げるだけでいいので一瞬ですみます。

特別にまずいという理由がなければ、B方式をお勧めします。私はいつもB方式を使っています。
お礼コメント
Nickee

お礼率 79% (107/134)

 なるほど。勉強になります。

2種類の方法がでているので、ポイントはあげられませんが、ありがとうございました。m (_ _) m
投稿日時 - 2002-02-08 13:53:27
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ