サイトマップ / C言語講座>出入り口>総目次>目次:数学の関数>問題解決について
学校の同じクラスに同じ誕生日の人がいることはそうありそうでなく、ありがちにも思えます。今日はその確率を求めます。
少子化の影響で、1クラスの人数も減る傾向にあります。そこで、1クラス23人とします。プログラムのなかに、23という数字を直接書き込むと、23という数字の意味が不明で、人数が変更になった時、特に、プログラムの中で複数回現れたりしていると変更が大変です。これを保守性が悪くなるといいます。
そこで、
#define NUM_STUDENTS 23.0
とします。コンパイルする前にプリプロセッサが働きますが、NUM_STUDENTSが出てきたら、プリプロセッサが23.0に書き換えてくれます。
なお、23人は整数であるにも関わらず23.0なのかというと、浮動小数点の計算に使われるからです。23でもコンパイルエラーは出ないはずですが、明示的に浮動小数点計算だということを示した方が良いと思います。
なお、long型の計算に用いられる数字は1000Lのように、unsigned long型の計算に用いられる数字は1000ULのように記述します。
では、実際にどういう方法で確率を求めたら良いでしょうか。そう簡単には思いつかないでしょう。そういう時には人数の少ないクラスから始めます。
重要:複雑な問題を解決するには最も単純な問題に分解してから始める。この手法は様々な局面で有効です。
1クラス2人から始めます。2人の誕生日が一致する確率は、1/365です。
クラスが3人になった時、3人のなかの2人が一致する確率は幾つでしょう。私には思いつきません。1人増えただけで問題が急速に難しくなってしまいました。そういう時はどうするか。別のアプローチを取ります。誕生日が一致しない確率を求めます。
1クラス2人から始めます。2人の誕生日が一致しない確率は、364 / 365です。
クラスが3人になった時、3人目が一致しない確率は、363 / 365です。従って、3人とも一致しない確率は、
( 364 / 365 ) * ( 363 / 365 )
となります。後は、23人迄、繰り返し計算をすれば良いわけです。これで、問題解決です。 */
#include <stdio.h> #define NUM_STUDENTS 23.0 void main(void); void main(void) { double prob; /* 誕生日が一致しない確率 */ double i ; prob = 364.0 / 365.0; /* もし2人なら */ for (i = 2.0; i < NUM_STUDENTS; i++) prob = prob * (365.0 - i) / 365.0; printf("誕生日が同じ人のいる確率 = %5.1lf%%\n", 100.0 - prob * 100.0); } |
/* printf( ) の中で、少し複雑なことをしているので、追加説明をします。
%5.1lf:小数点以下1桁の浮動小数点数に変換
%%:%2つで%を表示
100.0 - prob * 100.0:一致しない確率を%に変換して、100.0から引いたので一致する確率になる。
最初にプログラムのなかに数字を直接書き込むなといって置きながら、ずいぶん数字が書き込まれていると思った方もおられるでしょう。次のコードを見て下さい。
#define ZERO 0 #define ONE 1 #define TWO 2 #define THREE 3 int i = ZERO; int j = ONE; - - - - - -
これは、無駄ですね。1年が365日であることは自明です。自明なことは直接数字を書き込んでも良いと思います。それから、変数を初期化する時の0や1もそのまま書いて差し支えないと思います。要は、他の人がそれを見た時に直感的にわかるなら数字で良いと思います。 */
/* (C) 2000- YFプロ. All Rights Reserved. */ 提供:C言語講座−それ自体コンパイルできる教材を使った講座です−