[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

コンピュータIIB(Javaプログラミング入門)第6回

目次
6.1 乱数
6.1.1 乱数とは
6.1.2 乱数の使用例
6.2 条件文(3)
6.2.1 if-else文(2)
6.2.2 switch文
6.2.3 条件文の使用例(2)
6.3 演習6
6.4 レポート課題
6.5 参考文献
索引
case文   switch文   乱数  

6.1 乱数

6.1.1 乱数とは

乱数random numbers )とは、規則性のない数の列で、どの数も同じくらい現れるものです。 例えば、さいころを何回も振って出た目を並べると、1から6までの数の列ができますが、それには規則性はなく、それぞれの数も同じくらい現れるので、乱数と言えます。 乱数は、主にゲームで使われますが、シミュレーションや暗号などでも用いられます。

Javaでは、式 Math.random() で乱数が発生します。 発生する数は、0.0以上1.0未満の実数で、毎回異なります。

次のプログラムでは、乱数を1つ発生させています。 乱数なので、出力結果は下記とは違うでしょう。

/*  1*/ class RandomTest { // 乱数のテスト
/*  2*/     public static void main (String[] args) {
/*  3*/         double random;
/*  4*/         random = Math.random(); // 乱数を発生
/*  5*/         System.out.println(random);
/*  6*/     }
/*  7*/ }
asiaa1:~/comp2b b08a001$ java RandomTest
0.16865863188578234
asiaa1:~/comp2b b08a001$ java RandomTest
0.8440982279637195
asiaa1:~/comp2b b08a001$ java RandomTest
0.10163212550412803
asiaa1:~/comp2b b08a001$

6.1.2 乱数の使用例

例として、さいころのように1から6までの数をランダムに発生させることを考えます。 これは、次のように計算するとできます。

  1. 0.0以上1.0未満の乱数を発生させる。
  2. それを6倍すると、0.0以上6.0未満の乱数となる。
  3. それを整数に変換すると、0から5までの乱数となる。
  4. それに1を足すと、1から6までの乱数となる。

次のプログラムでは、1から6までの乱数を1つ発生させています。

/*  1*/ class RandomTest2 { // 乱数のテスト2
/*  2*/     public static void main (String[] args) {
/*  3*/         int random;
/*  4*/         random = ((int) (Math.random() * 6)) + 1; // 1から6までの乱数
/*  5*/         System.out.println(random);
/*  6*/     }
/*  7*/ }
asiaa1:~/comp2b b08a001$ java RandomTest2
5
asiaa1:~/comp2b b08a001$ java RandomTest2
5
asiaa1:~/comp2b b08a001$ java RandomTest2
4
asiaa1:~/comp2b b08a001$

6.2 条件文(3)

6.2.1 if-else文(2)

「もし何々が成り立つならば何々する」という条件文では、 if 文を使いました。 「もし何々が成り立つならば何々する。成り立たないならば何々する。」という条件文では、 if - else 文を使いました。

「何々が成り立つならば何々する。 そうでなくて、何々が成り立つならば何々する。 どちらも成り立たないならば何々する。 」というような条件文も考えられます。 これは次のように書きます。

if (条件1) {
    文1; ...
} else if (条件2) {
    文2; ...
} else {
    文3; ...
}

条件1 」が成り立つならば、「 文1 」、...が実行されます。 「 条件1 」が成り立たなくて、「 条件2 」が成り立つならば、「 文2 」、...が実行されます。 「 条件1 」も「 条件2 」も成り立たないならば、「 文3 」、...が実行されます。

多重if-else文の流れ
図 6.1  多重if-else文の流れ(true=成り立つ、false=成り立たない)

次のプログラムは、入力が正の数ならば「それは正の数です。」と出力し、負の数ならば「それは負の数です。」と出力するものです。 正の数でも負の数でもないならば、0のはずなので、「それは0です。」と出力します。

/*  1*/ import java.io.*;
/*  2*/
/*  3*/ class PositiveNegative { // 正の数・負の数
/*  4*/     public static void main (String[] args) throws IOException {
/*  5*/         InputStreamReader isr = new InputStreamReader(System.in);
/*  6*/         BufferedReader br = new BufferedReader(isr);
/*  7*/         int x;
/*  8*/         System.out.print("整数を入力してください: ");
/*  9*/         x = Integer.parseInt(br.readLine());
/* 10*/         if (x > 0) { // 正の数ならば
/* 11*/             System.out.println("それは正の数です。");
/* 12*/         } else if (x < 0) { // そうでなくて負の数ならば
/* 13*/             System.out.println("それは負の数です。");
/* 14*/         } else { // どれでもないならば
/* 15*/             System.out.println("それは0です。");
/* 16*/         }
/* 17*/     }
/* 18*/ }
asiaa1:~/comp2b b08a001$ java PositiveNegative
整数を入力してください: 100
それは正の数です。
asiaa1:~/comp2b b08a001$ java PositiveNegative
整数を入力してください: -30
それは負の数です。
asiaa1:~/comp2b b08a001$ java PositiveNegative
整数を入力してください: 0
それは0です。
asiaa1:~/comp2b b08a001$

条件がより多い場合は次のようになります。 「 条件1 」、「 条件2 」、...と順に確かめていき、初めて成り立つのが「 条件i 」ならば、「 文i 」、...が実行されます。 どの条件も成り立たないならば、「 文n+1 」、...が実行されます。

if (条件1) {
    文1; ...
} else if (条件2) {
    文2; ...
}
...
  else if (条件n) {
    文n; ...
} else {
    文n+1; ...
}

6.2.2 switch文

「もし式の値が1ならば何々する。2ならば何々する。…」という条件文は、条件が「式の値が何ならば」という特別なパターンですが、それなりに使われます。 Javaでは、そのような条件文のために、 switch 文が用意されています。

switch は、 case を伴い、次のように書きます。

switch () {
    case 定数1: 文1; ... break;
    case 定数2: 文2; ... break;
    ...
    case 定数n: 文n; ... break;
    default: 文n+1; ... break;
}

これで、「 」の値が「 定数1 」ならば「 文1 」、...が実行されます。 「 定数2 」ならば「 文2 」、...が実行されます。 以下同様ですが、どれでもないならば「 文n+1 」、...が実行されます。

case 文の定数は整数に限ります。 また、 case 文の定数は、1つの switch 文の中ではすべて異なるようにします。 case 文の並びの最後には、どれでもない場合を表す default を書きます。 それぞれの case 文の最後には、 break を書きます。

次のプログラムは、入力された数が3ならばtriangleと出力し、4ならばsquareと出力し、5ならばpentagonと出力し、それ以外ならばfigureと出力するものです。

/*  1*/ import java.io.*;
/*  2*/
/*  3*/ class SwitchTest { // switch文のテスト
/*  4*/     public static void main (String[] args) throws IOException {
/*  5*/         InputStreamReader isr = new InputStreamReader(System.in);
/*  6*/         BufferedReader br = new BufferedReader(isr);
/*  7*/         int x;
/*  8*/         System.out.print("整数を入力してください: ");
/*  9*/         x = Integer.parseInt(br.readLine());
/* 10*/         switch (x) { // xの値で場合分け
/* 11*/             case 3: System.out.println("triangle"); break; // 3の場合
/* 12*/             case 4: System.out.println("square"); break; // 4の場合
/* 13*/             case 5: System.out.println("pentagon"); break; // 5の場合
/* 14*/             default: System.out.println("figure"); break; // どれでもない場合
/* 15*/         }
/* 16*/     }
/* 17*/ }
asiaa1:~/comp2b b08a001$ java SwitchTest
整数を入力してください: 3
triangle
asiaa1:~/comp2b b08a001$ java SwitchTest
整数を入力してください: 4
square
asiaa1:~/comp2b b08a001$ java SwitchTest
整数を入力してください: 5
pentagon
asiaa1:~/comp2b b08a001$ java SwitchTest
整数を入力してください: 6
figure
asiaa1:~/comp2b b08a001$

switch 文を使わなくても、 if - else 文を使えば同じことができます。 ただし、プログラムは多少長くなります。 以下のプログラムと比較してください。

/*  1*/ import java.io.*;
/*  2*/
/*  3*/ class SwitchTest2 { // switch文のテスト2
/*  4*/     public static void main (String[] args) throws IOException {
/*  5*/         InputStreamReader isr = new InputStreamReader(System.in);
/*  6*/         BufferedReader br = new BufferedReader(isr);
/*  7*/         int x;
/*  8*/         System.out.print("整数を入力してください: ");
/*  9*/         x = Integer.parseInt(br.readLine());
/* 10*/         if (x == 3) {
/* 11*/             System.out.println("triangle");
/* 12*/         } else if (x == 4) {
/* 13*/             System.out.println("square");
/* 14*/         } else if (x == 5) {
/* 15*/             System.out.println("pentagon");
/* 16*/         } else {
/* 17*/             System.out.println("figure");
/* 18*/         }
/* 19*/     }
/* 20*/ }

6.2.3 条件文の使用例(2)

条件文の使用例として、2次方程式、うるう年、およびじゃんけんについて考えます。

2次方程式 ax 2 + bx + c = 0( a ≠0)の解き方は次の通りです。

  1. 判別式 D = b 2 - 4 ac を計算する。
  2. D = 0 ならば、解は 1 つ (- b ) / (2 a ).
  3. D > 0 ならば、解は 2 つ (- b ±√ D ) / (2 a ).
  4. D < 0 ならば、(実数)解はない。

これをプログラムにすると、次のようになります。 例えば、2次方程式 x 2 - 4 x + 3 = 0 の解は、3 と 1 です。

/*  1*/ import java.io.*;
/*  2*/ 
/*  3*/ class QuadraticEquation { // 2次方程式
/*  4*/     public static void main (String[] args) throws IOException {
/*  5*/         InputStreamReader isr = new InputStreamReader(System.in);
/*  6*/         BufferedReader br = new BufferedReader(isr);
/*  7*/         double a, b, c, d;
/*  8*/         System.out.print("a = ");
/*  9*/         a = Double.parseDouble(br.readLine());
/* 10*/         System.out.print("b = ");
/* 11*/         b = Double.parseDouble(br.readLine());
/* 12*/         System.out.print("c = ");
/* 13*/         c = Double.parseDouble(br.readLine());
/* 14*/         d = b * b - 4.0 * a * c; // 判別式
/* 15*/         if (Math.abs(d) < 1.0E-10) { // 0.0とほとんど等しい
/* 16*/             System.out.println(-b / (2.0 * a));
/* 17*/         } else if (d > 0.0) {
/* 18*/             System.out.println((-b + Math.sqrt(d)) / (2.0 * a));
/* 19*/             System.out.println((-b - Math.sqrt(d)) / (2.0 * a));
/* 20*/         } else { // (d < 0.0)
/* 21*/             System.out.println("実数解はありません。");
/* 22*/         }
/* 23*/     }
/* 24*/ }
asiaa1:~/comp2b b08a001$ java QuadraticEquation
a = 1.0
b = -4.0
c = 3.0
3.0
1.0
asiaa1:~/comp2b b08a001$ java QuadraticEquation
a = 1.0
b = -4.0
c = 4.0
2.0
asiaa1:~/comp2b b08a001$ java QuadraticEquation
a = 1.0
b = -4.0
c = 5.0
実数解はありません。
asiaa1:~/comp2b b08a001$

うるう年は次のように決められます。

  1. 西暦が4で割り切れるならば、うるう年である。
  2. 例外として、100で割り切れるならば、うるう年でない。
  3. 例外の例外として、400で割り切れるならば、うるう年である。

これをそのままプログラムにすると、次のようになります。

/*  1*/ import java.io.*;
/*  2*/ 
/*  3*/ class LeapYear { // うるう年
/*  4*/     public static void main (String[] args) throws IOException {
/*  5*/         InputStreamReader isr = new InputStreamReader(System.in);
/*  6*/         BufferedReader br = new BufferedReader(isr);
/*  7*/         int year;
/*  8*/         System.out.print("西暦を入力してください: ");
/*  9*/         year = Integer.parseInt(br.readLine());
/* 10*/         if (year % 4 == 0) {
/* 11*/             if (year % 100 == 0) {
/* 12*/                 if (year % 400 == 0) {
/* 13*/                     System.out.println("うるう年です。");
/* 14*/                 } else { // 4と100で割り切れて400で割り切れない
/* 15*/                     System.out.println("うるう年ではありません。");
/* 16*/                 }
/* 17*/             } else { // 4で割り切れて100で割り切れない
/* 18*/                 System.out.println("うるう年です。");
/* 19*/             }
/* 20*/         } else { // 4で割り切れない
/* 21*/             System.out.println("うるう年ではありません。");
/* 22*/         }
/* 23*/     }
/* 24*/ }
asiaa1:~/comp2b b08a001$ java LeapYear
西暦を入力してください: 2000
うるう年です。
asiaa1:~/comp2b b08a001$ java LeapYear
西暦を入力してください: 2010
うるう年ではありません。
asiaa1:~/comp2b b08a001$ java LeapYear
西暦を入力してください: 2020
うるう年です。
asiaa1:~/comp2b b08a001$ java LeapYear
西暦を入力してください: 2100
うるう年ではありません。
asiaa1:~/comp2b b08a001$

条件の順序を逆にすると、プログラムが分かりやすくなります。

/*  1*/ import java.io.*;
/*  2*/
/*  3*/ class LeapYear2 { // うるう年2
/*  4*/     public static void main (String[] args) throws IOException {
/*  5*/         InputStreamReader isr = new InputStreamReader(System.in);
/*  6*/         BufferedReader br = new BufferedReader(isr);
/*  7*/         int year;
/*  8*/         System.out.print("西暦を入力してください: ");
/*  9*/         year = Integer.parseInt(br.readLine());
/* 10*/         if (year % 400 == 0) { // 400で割り切れる
/* 11*/             System.out.println("うるう年です。");
/* 12*/         } else if (year % 100 == 0) { // そうでなくて100で割り切れる
/* 13*/             System.out.println("うるう年ではありません。");
/* 14*/         } else if (year % 4 == 0) { // そうでなくて4で割り切れる
/* 15*/             System.out.println("うるう年です。");
/* 16*/         } else { // どれでもない
/* 17*/             System.out.println("うるう年ではありません。");
/* 18*/         }
/* 19*/     }
/* 20*/ }

実は、プログラムをもっと簡単にできます。 うるう年になるパターンは

のどちらかなので、その通りにプログラムを作ります。

/*  1*/ import java.io.*;
/*  2*/
/*  3*/ class LeapYear3 { // うるう年3
/*  4*/     public static void main (String[] args) throws IOException {
/*  5*/         InputStreamReader isr = new InputStreamReader(System.in);
/*  6*/         BufferedReader br = new BufferedReader(isr);
/*  7*/         int year;
/*  8*/         System.out.print("西暦を入力してください: ");
/*  9*/         year = Integer.parseInt(br.readLine());
/* 10*/         if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
/* 11*/             System.out.println("うるう年です。");
/* 12*/         } else {
/* 13*/             System.out.println("うるう年ではありません。");
/* 14*/         }
/* 15*/     }
/* 16*/ }

じゃんけんプログラムでは、同じ確率でランダムに「グー」、「チョキ」、「パー」を出すことにします。 0から2までの乱数を発生させ、0ならば「グー」を、1ならば「チョキ」を、2ならば「パー」を、それぞれ出力します。

/*  1*/ class RandomJanken { // ランダムなじゃんけん
/*  2*/     public static void main (String[] args) {
/*  3*/         int random;
/*  4*/         random = (int) (Math.random() * 3); // 0から2までの乱数
/*  5*/         switch (random) {
/*  6*/             case 0: System.out.println("グー"); break;
/*  7*/             case 1: System.out.println("チョキ"); break;
/*  8*/             case 2: System.out.println("パー"); break;
/*  9*/             default: System.out.println("エラー"); break;
/* 10*/         }
/* 11*/     }
/* 12*/ }
asiaa1:~/comp2b b08a001$ java RandomJanken
パー
asiaa1:~/comp2b b08a001$ java RandomJanken
パー
asiaa1:~/comp2b b08a001$ java RandomJanken
チョキ
asiaa1:~/comp2b b08a001$

6.3 演習6

おみくじプログラムを作成してください。 「大吉」、「吉」、「中吉」、「小吉」、「凶」の5種類の運勢が、同じ確率でランダムに出力されるようにしてください。

asiaa1:~/comp2b b08a001$ java RandomOmikuji
大吉
asiaa1:~/comp2b b08a001$ java RandomOmikuji
大吉
asiaa1:~/comp2b b08a001$ java RandomOmikuji
吉
asiaa1:~/comp2b b08a001$

余力のある人は、運勢の種類(個数と語句)を変えたものも作成してください。


6.4 レポート課題

今日の演習6の答案(Javaプログラム)をメールで提出してください。 差出人は学内のメール・アドレス(b08a001@cis.twcu.ac.jpなど)とし、宛先はkonishi@cis.twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(6月3日)を明記してください。


6.5 参考文献


[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

2011年6月3日更新
小西 善二郎 <konishi@cis.twcu.ac.jp>
Copyright (C) 2011 Zenjiro Konishi. All rights reserved.