乱数 ( 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*/ }
Z:\Desktop\java1>java RandomTest 0.16865863188578234 Z:\Desktop\java1>java RandomTest 0.8440982279637195 Z:\Desktop\java1>java RandomTest 0.10163212550412803 Z:\Desktop\java1>
例として、さいころのように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*/ }
Z:\Desktop\java1>java RandomTest2 5 Z:\Desktop\java1>java RandomTest2 5 Z:\Desktop\java1>java RandomTest2 4 Z:\Desktop\java1>
「もし何々が成り立つならば何々する」という条件文では、if文を使いました。 「もし何々が成り立つならば何々する。成り立たないならば何々する。」という条件文では、if-else文を使いました。
「何々が成り立つならば何々する。 そうでなくて、何々が成り立つならば何々する。 どちらも成り立たないならば何々する。 」というような条件文も考えられます。 これは次のように書きます。
if (条件1) { 文1; ... } else if (条件2) { 文2; ... } else { 文3; ... }
「 条件1 」が成り立つならば、「 文1 」、...が実行されます。 「 条件1 」が成り立たなくて、「 条件2 」が成り立つならば、「 文2 」、...が実行されます。 「 条件1 」も「 条件2 」も成り立たないならば、「 文3 」、...が実行されます。
次のプログラムは、入力が正の数ならば「それは正の数です。」と出力し、負の数ならば「それは負の数です。」と出力するものです。 正の数でも負の数でもないならば、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*/ }
Z:\Desktop\java1>java PositiveNegative 整数を入力してください: 100 それは正の数です。 Z:\Desktop\java1>java PositiveNegative 整数を入力してください: -30 それは負の数です。 Z:\Desktop\java1>java PositiveNegative 整数を入力してください: 0 それは0です。 Z:\Desktop\java1>
条件がより多い場合は次のようになります。 「 条件1 」、「 条件2 」、...と順に確かめていき、初めて成り立つのが「 条件i 」ならば、「 文i 」、...が実行されます。 どの条件も成り立たないならば、「 文n+1 」、...が実行されます。
if (条件1) { 文1; ... } else if (条件2) { 文2; ... } ... else if (条件n) { 文n; ... } else { 文n+1; ... }
「もし式の値が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*/ }
Z:\Desktop\java1>java SwitchTest 整数を入力してください: 3 triangle Z:\Desktop\java1>java SwitchTest 整数を入力してください: 4 square Z:\Desktop\java1>java SwitchTest 整数を入力してください: 5 pentagon Z:\Desktop\java1>java SwitchTest 整数を入力してください: 6 figure Z:\Desktop\java1>
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*/ }
条件文の使用例として、2次方程式、月の最終日、曜日の計算、およびじゃんけんについて考えます。
2次方程式 ax 2 + bx + c =0( a ≠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*/ }
Z:\Desktop\java1>java QuadraticEquation a = 1.0 b = -4.0 c = 3.0 3.0 1.0 Z:\Desktop\java1>java QuadraticEquation a = 1.0 b = -4.0 c = 4.0 2.0 Z:\Desktop\java1>java QuadraticEquation a = 1.0 b = -4.0 c = 5.0 実数解はありません。 Z:\Desktop\java1>
月の最終日は、小の月(2月、4月、6月、9月、11月)ならば30日、大の月(それ以外)ならば31日です。 ただし、2月は例外で、うるう年ならば29日、そうでないならば28日です。 うるう年の判定は、前回の授業で説明しました。
/* 1*/ import java.io.*; /* 2*/ /* 3*/ class LastDayOfMonth { // 月の最終日 /* 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, month, lastDay; /* 8*/ System.out.print("年を入力してください: "); /* 9*/ year = Integer.parseInt(br.readLine()); /* 10*/ System.out.print("月を入力してください: "); /* 11*/ month = Integer.parseInt(br.readLine()); /* 12*/ if (month == 2) { /* 13*/ if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) { /* 14*/ lastDay = 29; // うるう年の2月 /* 15*/ } else { /* 16*/ lastDay = 28; // うるう年でない2月 /* 17*/ } /* 18*/ } else if (month == 4 || month == 6 || month == 9 || month == 11) { /* 19*/ lastDay = 30; // 2月以外の小の月 /* 20*/ } else { /* 21*/ lastDay = 31; // 大の月 /* 22*/ } /* 23*/ System.out.println(lastDay); /* 24*/ } /* 25*/ }
Z:\Desktop\java1>java LastDayOfMonth 年を入力してください: 2016 月を入力してください: 2 29 Z:\Desktop\java1>java LastDayOfMonth 年を入力してください: 2019 月を入力してください: 2 28 Z:\Desktop\java1>java LastDayOfMonth 年を入力してください: 2019 月を入力してください: 9 30 Z:\Desktop\java1>java LastDayOfMonth 年を入力してください: 2019 月を入力してください: 10 31 Z:\Desktop\java1>
曜日の計算は、ツェラー(Zeller)の公式という有名な公式で計算します。 これは、西暦 y 年 m 月 d 日ならば、式
を計算し、 h が0ならば日曜日、1ならば月曜日、2ならば火曜日、3ならば水曜日、4ならば木曜日、5ならば金曜日、6ならば土曜日とするものです。 ここで、[…]は床関数(正なら小数切り捨て)、modは剰余演算(割った余り)です。 ただし、1月と2月については、前年の13月と14月と考えます。
/* 1*/ import java.io.*; /* 2*/ /* 3*/ class DayOfWeek { // 曜日の計算 /* 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, month, day, y, m, h; /* 8*/ System.out.print("西暦を入力してください: "); /* 9*/ year = Integer.parseInt(br.readLine()); /* 10*/ System.out.print("月を入力してください: "); /* 11*/ month = Integer.parseInt(br.readLine()); /* 12*/ System.out.print("日を入力してください: "); /* 13*/ day = Integer.parseInt(br.readLine()); /* 14*/ if (month == 1 || month == 2) { // 1月と2月は /* 15*/ y = year - 1; // 前年の /* 16*/ m = month + 12; // 13月と14月とする /* 17*/ } else { /* 18*/ y = year; /* 19*/ m = month; /* 20*/ } /* 21*/ // ツェラーの公式 /* 22*/ h = (y + y / 4 - y / 100 + y / 400 + (13 * m + 8) / 5 + day) % 7; /* 23*/ switch (h) { /* 24*/ case 0: System.out.println("日曜日"); break; /* 25*/ case 1: System.out.println("月曜日"); break; /* 26*/ case 2: System.out.println("火曜日"); break; /* 27*/ case 3: System.out.println("水曜日"); break; /* 28*/ case 4: System.out.println("木曜日"); break; /* 29*/ case 5: System.out.println("金曜日"); break; /* 30*/ case 6: System.out.println("土曜日"); break; /* 31*/ default: System.out.println("エラー"); break; /* 32*/ } /* 33*/ } /* 34*/ }
Z:\Desktop\java1>java DayOfWeek 西暦を入力してください: 2019 月を入力してください: 11 日を入力してください: 1 金曜日 Z:\Desktop\java1>
じゃんけんプログラムでは、同じ確率でランダムに「グー」、「チョキ」、「パー」を出すことにします。 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*/ }
Z:\Desktop\java1>java RandomJanken パー Z:\Desktop\java1>java RandomJanken パー Z:\Desktop\java1>java RandomJanken チョキ Z:\Desktop\java1>
おみくじプログラムを作成してください。 「大吉」、「吉」、「中吉」、「小吉」、「凶」の5種類の運勢が、同じ確率でランダムに出力されるようにしてください。
Z:\Desktop\java1>java RandomOmikuji 大吉 Z:\Desktop\java1>java RandomOmikuji 大吉 Z:\Desktop\java1>java RandomOmikuji 吉 Z:\Desktop\java1>
余力のある人は、運勢の種類(個数と語句)を変えたものも作成してください。
今日の演習6の答案(Javaプログラム)をメールで提出してください。 差出人は学内のメール・アドレス(学生番号@cis.twcu.ac.jp)とし、宛先はkonishi@cis.twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(11月1日)を明記してください。