ネットが遅くてイライラしてない!?

初歩的な質問ですみません。
参考書のじゃんけんゲームのプログラムでコンピューター側の手を乱数で
rand()%3;
と表現しているのですが、
ある特定の範囲の乱数を使うために、剰余を用いるのはなぜなのでしょうか?

いまいち理解できず、質問させていただきました。
どなたか分かりやすく教えてくださると助かります。
よろしくお願いいたします。

A 回答 (4件)

例えば、rand(3); のように引数で範囲を指定できれば問題はないのですが、残念ながらrand関数では引数を用いません。



ここで、ある数字(例えば、23)がランダムで出力されたとします。
プログラムではこの数字に『グー、チョキ、パー』のいづれかを割り当てなければなりません。

「23が出てきたからグー」みたいな処理になります。

必要な条件は、『グー、チョキ、パー』が同じくらいの割合で出現することです。
(厳密には"ランダム"なので確率が偏ってもいいのですが、プログラムで意図的に偏らせてはランダムではなくなります)

整数の集合をn個の集合に分割する方法として、モジュロ演算があります。(時計算術、剰余演算とも言われます)

6 ≡ 9 (modulo 3) ← 6と9は、3で割った余りが等しいと言う意味

これを用いれば、直ちに 23 ≡ 2 (modulo 3) と瞬時にわかります。
C言語では 23 % 3 == 2 となります。

つまり、『グー、チョキ、パー』に『1, 2, 3』を割当て、ランダムな数字にモジュロ演算をかければ、『1, 2, 3』のいづれかを得て『グー、チョキ、パー』に変換できると言うわけです。
    • good
    • 0

No.1 の人が言ってる「ちょっと困る」については、これ↓でも参考に。


https://omitakahiro.github.io/random/random_vari …
    • good
    • 0

rand() は 0〜RAND_MAXのランダムな値になります。


RAND_MAXは 32767以上となっています。

仮に、 RAND_MAX= 32767 として。
そのままでは、0〜32767で 32768通りの値を取ります。

今回、0,1,2の3通りを使いたいわけですが、どうするか、方法はいくつかあります。
代表的なのは次の2つでしょう。

(1) 0,1,2 以外だったらもう一度rand()で値を得る。
 → 凄く非効率的です。
rand()関数の性質上、確率の隔りが大きくなる可能性があります(まったく出現しないことも)

(2) 32768通りの値を(だいたい)3等分にグループ分けして、それぞれを 0,1,2 に割り当てる。
これなら効率良く0,1,2 を得られます。


(2)のグループ分けする方法は、(だいたい)3等分にできればなんでもいいです。
 0,1,2,3,5,9 ... → 0
 4,7,8,13,... → 1
 残り → 2
等と不規則でも3等分にできていればOKです。
ですが、それでは効率が悪いので、「なにかの計算式でグループ分けする」方法を使います。

その「なにかの計算式でグループ分けする」方法の一つが「余りでグループ分け」です。
3で割った余りが0のグループ、1のグループ、2のグループと3等分できます。
    • good
    • 0

簡単だから.



もっとも, 本当にこれだけだとちょっと困るんだけど.
    • good
    • 0

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

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング