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

情報処理技法(Javaプログラミング)I 第5回

目次
索引

乱数

乱数とは

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

次のプログラムは、0から99までの乱数を生成するものです。 乱数なので、出力結果は下記とは違うのですが、プログラムを実行するたびに、違う数が出力されています。

RandomTest.java
import java.util.Random; // 乱数のときに書く

class RandomTest { // 乱数のときに書く
    public static void main (String[] args) { // 乱数のときに書く
        Random rand = new Random(); // 乱数のときに書く
        int r;
        r = rand.nextInt(100); // 0から99までの乱数を生成
        System.out.println(r);
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'RandomTest'
57
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'RandomTest'
78
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'RandomTest'
66
PS ...\Desktop\java1>

乱数を生成するプログラムでは、1行目から5行目まではそのまま書くものと考えてください。 ただし、3行目はファイル名によって変わります。

7行目で乱数が生成されます。 一般的に、式

rand.nextInt(n)

によって、 n 種類の整数の乱数が生成されます。 このとき、整数は0から始めますので、乱数は0から n -1までとなります。 このプログラムでは、 n =100なので、0から99までの乱数となります。

整数だけでなく、実数の乱数も生成できます。 式

rand.nextDouble()

によって、0.0以上1.0未満の実数の乱数が生成されます。

乱数の使用例

さて、さいころのように1から6までの数をランダムに生成するには、どうしたらいいでしょうか。 これは、式

rand.nextInt(6) + 1

を計算するとできます。 0から5までの乱数に1を足すと、1から6までの乱数になるのです。

同様に、0.0以上100.0未満の実数の乱数を生成したければ、

rand.nextDouble() * 100.0

とすればよいのです。

RandomTest2.java
import java.util.Random;

class RandomTest2 { // 乱数のテスト2
    public static void main (String[] args) {
        Random rand = new Random();
        double r;
        r = rand.nextDouble() * 100.0; // 0.0以上100.0未満の乱数
        System.out.println(r);
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'RandomTest2'
56.519319874125614
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'RandomTest2'
7.722231709709925
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'RandomTest2'
2.046519254643775
PS ...\Desktop\java1>

条件文(3)

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文の流れ
多重if-else文の流れ(true=成り立つ、false=成り立たない)

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

PositiveNegative.java
import java.util.Scanner;

class PositiveNegative { // 正の数・負の数
    public static void main (String[] args) {
        Scanner stdIn = new Scanner(System.in);
        int x;
        System.out.print("整数を入力してください: ");
        x = stdIn.nextInt();
        if (x > 0) { // 正の数ならば
            System.out.println("それは正の数です。");
        } else if (x < 0) { // そうでなくて負の数ならば
            System.out.println("それは負の数です。");
        } else { // どれでもないならば
            System.out.println("それは0です。");
        }
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'PositiveNegative'
整数を入力してください: 100
それは正の数です。
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'PositiveNegative'
整数を入力してください: -30
それは負の数です。
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'PositiveNegative'
整数を入力してください: 0
それは0です。
PS ...\Desktop\java1>

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

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

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と出力するものです。

SwitchTest.java
import java.util.Scanner;

class SwitchTest { // switch文のテスト
    public static void main (String[] args) {
        Scanner stdIn = new Scanner(System.in);
        int x;
        System.out.print("整数を入力してください: ");
        x = stdIn.nextInt();
        switch (x) { // xの値で場合分け
            case 3: System.out.println("triangle"); break; // 3の場合
            case 4: System.out.println("square"); break; // 4の場合
            case 5: System.out.println("pentagon"); break; // 5の場合
            default: System.out.println("figure"); break; // どれでもない場合
        }
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'SwitchTest'
整数を入力してください: 3
triangle
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'SwitchTest'
整数を入力してください: 4
square
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'SwitchTest'
整数を入力してください: 5
pentagon
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'SwitchTest'
整数を入力してください: 6
figure
PS ...\Desktop\java1>

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

SwitchTest2.java
import java.util.Scanner;

class SwitchTest2 { // switch文のテスト2
    public static void main (String[] args) {
        Scanner stdIn = new Scanner(System.in);
        int x;
        System.out.print("整数を入力してください: ");
        x = stdIn.nextInt();
        if (x == 3) {
            System.out.println("triangle");
        } else if (x == 4) {
            System.out.println("square");
        } else if (x == 5) {
            System.out.println("pentagon");
        } else {
            System.out.println("figure");
        }
    }
}

条件文の使用例(2)

条件文の使用例として、2次方程式、月の最終日、曜日の計算、およびじゃんけんについて考えます。

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

  1. 判別式 D b 2 −4 ac を計算する。
  2. D =0ならば、解は1つ:
    2次方程式の解
  3. D >0ならば、解は2つ:
    2次方程式の解
  4. D <0ならば、(実数)解はない。

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

QuadraticEquation.java
import java.util.Scanner;

class QuadraticEquation { // 2次方程式
    public static void main (String[] args) {
        Scanner stdIn = new Scanner(System.in);
        double a, b, c, d;
        System.out.print("a = ");
        a = stdIn.nextDouble();
        System.out.print("b = ");
        b = stdIn.nextDouble();
        System.out.print("c = ");
        c = stdIn.nextDouble();
        d = b * b - 4.0 * a * c; // 判別式
        if (Math.abs(d) < 1.0E-10) { // 0.0とほとんど等しい
            System.out.println(-b / (2.0 * a));
        } else if (d > 0.0) {
            System.out.println((-b + Math.sqrt(d)) / (2.0 * a));
            System.out.println((-b - Math.sqrt(d)) / (2.0 * a));
        } else { // (d < 0.0)
            System.out.println("実数解はありません。");
        }
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'QuadraticEquation'
a = 1.0
b = -4.0
c = 3.0
3.0
1.0
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'QuadraticEquation'
a = 1.0
b = -4.0
c = 4.0
2.0
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'QuadraticEquation'
a = 1.0
b = -4.0
c = 5.0
実数解はありません。
PS ...\Desktop\java1>

月の最終日は、小の月(2月、4月、6月、9月、11月)ならば30日、大の月(それ以外)ならば31日です。 ただし、2月は例外で、うるう年ならば29日、そうでないならば28日です。 うるう年の判定は、前回の授業で説明しました。

LastDayOfMonth.java
import java.util.Scanner;

class LastDayOfMonth { // 月の最終日
    public static void main (String[] args) {
        Scanner stdIn = new Scanner(System.in);
        int year, month, lastDay;
        System.out.print("年を入力してください: ");
        year = stdIn.nextInt();
        System.out.print("月を入力してください: ");
        month = stdIn.nextInt();
        if (month == 2) {
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                lastDay = 29; // うるう年の2月
            } else {
                lastDay = 28; // うるう年でない2月
            }
        } else if (month == 4 || month == 6 || month == 9 || month == 11) {
            lastDay = 30; // 2月以外の小の月
        } else {
            lastDay = 31; // 大の月
        }
        System.out.println(lastDay);
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'LastDayOfMonth'
年を入力してください: 2024
月を入力してください: 2
29
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'LastDayOfMonth'
年を入力してください: 2025
月を入力してください: 2
28
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'LastDayOfMonth'
年を入力してください: 2025
月を入力してください: 4
30
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'LastDayOfMonth'
年を入力してください: 2025
月を入力してください: 5
31
PS ...\Desktop\java1>

曜日の計算は、ツェラー(Zeller)の公式という有名な公式で計算します。 これは、西暦 y m d 日ならば、式

ツェラーの公式

を計算し、 h が0ならば日曜日、1ならば月曜日、2ならば火曜日、3ならば水曜日、4ならば木曜日、5ならば金曜日、6ならば土曜日とするものです。 ここで、[…]は床関数(正なら小数切り捨て)、modは剰余演算(割った余り)です。 ただし、1月と2月については、前年の13月と14月と考えます。

DayOfWeek.java
import java.util.Scanner;

class DayOfWeek { // 曜日の計算
    public static void main (String[] args) {
        Scanner stdIn = new Scanner(System.in);
        int year, month, day, y, m, h;
        System.out.print("西暦を入力してください: ");
        year = stdIn.nextInt();
        System.out.print("月を入力してください: ");
        month = stdIn.nextInt();
        System.out.print("日を入力してください: ");
        day = stdIn.nextInt();
        if (month == 1 || month == 2) { // 1月と2月は
            y = year - 1; // 前年の
            m = month + 12; // 13月と14月とする
        } else {
            y = year;
            m = month;
        }
        // ツェラーの公式
        h = (y + y / 4 - y / 100 + y / 400 + (13 * m + 8) / 5 + day) % 7;
        switch (h) {
            case 0: System.out.println("日曜日"); break;
            case 1: System.out.println("月曜日"); break;
            case 2: System.out.println("火曜日"); break;
            case 3: System.out.println("水曜日"); break;
            case 4: System.out.println("木曜日"); break;
            case 5: System.out.println("金曜日"); break;
            case 6: System.out.println("土曜日"); break;
            default: System.out.println("エラー"); break;
        }
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'DayOfWeek'
西暦を入力してください: 2025
月を入力してください: 5
日を入力してください: 9
金曜日
PS ...\Desktop\java1>

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

RandomJanken.java
import java.util.Random;

class RandomJanken { // ランダムなじゃんけん
    public static void main (String[] args) {
        Random rand = new Random();
        int r;
        r = rand.nextInt(3); // 0から2までの乱数
        switch (r) {
            case 0: System.out.println("グー"); break;
            case 1: System.out.println("チョキ"); break;
            case 2: System.out.println("パー"); break;
            default: System.out.println("エラー"); break;
        }
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'RandomJanken'
パー
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'RandomJanken'
パー
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'RandomJanken'
チョキ
PS ...\Desktop\java1>

演習5

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

RandomOmikuji.java
import java.util.Random;

class RandomOmikuji {
    public static void main (String[] args) {
        Random rand = new Random();
        
        
        
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'RandomOmikuji'
大吉
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'RandomOmikuji'
大吉
PS ...\Desktop\java1>
ターミナル
PS ...\Desktop\java1>  & ... 'RandomOmikuji'
吉
PS ...\Desktop\java1>

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


レポート課題

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


参考文献


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

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