Javaプログラミング基礎講座:段階的に学ぶJavaの基本と実践(コース資料)

本コースは、Javaプログラムの基本構造と制御構造を体系的に学習する全6回の演習である。

カリキュラム構成

本コースは以下の2つの部で構成される。

  1. 第1部:基礎(ji-1〜ji-2)

    プログラムの基本構造と標準ライブラリの活用

  2. 第2部:制御構造とデータ構造(ji-3〜ji-6)

    条件分岐、繰り返し処理、配列によるプログラム制御とデータ管理

学習内容一覧

タイトル 主要な学習内容
ji-1 Javaプログラミング入門:基本的なプログラム構造と開発環境の活用 プログラムの基本構造、開発環境
ji-2 Javaプログラミングにおける基本計算と標準ライブラリの活用 数値計算、標準ライブラリ
ji-3 条件分岐とプログラム制御:Javaプログラムの基本構造 if文、条件分岐
ji-4 Javaプログラミングにおける基本データ型と数値計算の基礎 基本データ型、数値計算
ji-5 Javaプログラミングにおける繰り返し処理と数値計算の基礎 while文、for文、入れ子構造
ji-6 Javaプログラミングにおける配列と数値計算アルゴリズムの基礎 配列、数値計算アルゴリズム

到達目標

条件分岐と繰り返し処理を組み合わせたプログラムの作成、配列を用いたデータ管理

授業の特徴

入力・処理・出力の基本構造から、入れ子構造を用いた複雑な処理まで段階的に学習する構成

【関連する外部ページ】

教材の利用条件: クリエイティブコモンズ 表示-非営利-継承 4.0 国際ライセンス(CC BY-NC-SA 4.0)に基づき、著作者表示・非営利目的・同一ライセンスでの再配布を条件として自由に利用可能である。

1. Javaプログラミング入門:基本的なプログラム構造と開発環境の活用

資料(スライド):ji-1. Javaプログラミング入門:基本的なプログラム構造と開発環境の活用 [PDF], [パワーポイント]

演習パート(クリックして展開)

学習の準備:Online GDB の使用

本演習では、オンライン開発環境 Online GDB を使用してJavaプログラムを実行する。

  1. ウェブブラウザを起動する
  2. https://www.onlinegdb.com を開く
  3. 画面上部の「Language」で「Java」を選択する
  4. エディタ画面にプログラムを入力し、「Run」ボタンで実行する

注意:Online GDB はオンラインサービスであるため、秘密にしたいプログラムの取り扱いには注意が必要である。

使用するプログラムの概要

このガイドでは、sin関数の値を計算するプログラムを使用する。このプログラムは以下の3つの機能を持つ。

ソースコードの入力

以下のソースコードをエディタ画面に入力する。

import java.lang.Math;
import java.util.Scanner;

public class Main
{
    public static void main(String[] args) {
        double start_x, step_x, x, y;
        int i;
        Scanner s = new Scanner(System.in);

        System.out.println("Please Enter start_x =");
        start_x = s.nextDouble();

        System.out.println("Please Enter step_x =");
        step_x = s.nextDouble();

        for (i = 1; i <= 20; i++) {
            x = start_x + (i * step_x);
            y = Math.sin(x);
            System.out.printf("sin(%8.3f) = %8.3f\n", x, y);
        }
    }
}

プログラムの強制終了

プログラムが停止しない場合は、「Stop」ボタンをクリックして強制終了できる。

演習1:sin関数の値の確認

目的

プログラムを実行し、入力値から計算結果が得られる流れを体験する。start_xとstep_xの役割を理解し、目的の計算結果を得るための入力値を考える。

手順

  1. エディタ画面にソースコードが入力されていることを確認する
  2. 「Run」ボタンをクリックしてプログラムを実行する
  3. 「Please Enter start_x =」と表示されたら、start_xの値を入力してEnterキーを押す
  4. 「Please Enter step_x =」と表示されたら、step_xの値を入力してEnterキーを押す
  5. 計算結果が20行表示されるので、sin(0.4)の値を探す

ヒント

確認ポイント

演習2:構文エラーの確認

目的

プログラムに意図的な誤りを入れ、開発環境の構文チェック(コンパイル時にプログラムの誤りを検出する機能)の動作を確認する。

手順

  1. エディタ画面で、以下の部分を見つける
    y = Math.sin(x);
  2. 「sin」を「son」に書き換える
    y = Math.son(x);
  3. 「Run」ボタンをクリックする
  4. 表示されるエラーメッセージを観察する
  5. 確認後、「son」を「sin」に戻して正常に実行できることを確認する

ヒント

確認ポイント

演習3:cos関数への書き換え

目的

プログラムを修正して異なる計算を実行する。sin関数をcos関数に変更し、プログラムの一部を変更するだけで異なる計算が可能になることを理解する。

手順

  1. エディタ画面で、以下の2箇所を書き換える

    変更箇所1(計算部分):

    y = Math.sin(x);

    を以下に変更する。

    y = Math.cos(x);

    変更箇所2(表示部分):

    System.out.printf("sin(%8.3f) = %8.3f\n", x, y);

    を以下に変更する。

    System.out.printf("cos(%8.3f) = %8.3f\n", x, y);
  2. 「Run」ボタンをクリックしてプログラムを実行する
  3. 演習1と同様の考え方で、cos(0.4)の値が表示されるようにstart_xとstep_xの値を入力する
  4. 計算結果を確認する

ヒント

確認ポイント

2. Javaプログラミングにおける基本計算と標準ライブラリの活用

資料(スライド):ji-2. Javaプログラミングにおける基本計算と標準ライブラリの活用 [PDF], [パワーポイント]

演習パート(クリックして展開)

学習の準備:Online GDB の使用

本演習では、オンライン開発環境 Online GDB を使用してJavaプログラムを実行する。

  1. ウェブブラウザを起動する
  2. https://www.onlinegdb.com を開く
  3. 画面上部の「Language」で「Java」を選択する
  4. エディタ画面にプログラムを入力し、「Run」ボタンで実行する

注意:Online GDB はオンラインサービスであるため、秘密にしたいプログラムの取り扱いには注意が必要である。

演習1:Heronの公式による三角形の面積計算

目的

3辺の長さから三角形の面積を求めるHeronの公式をJavaで実装し、変数宣言、入出力、標準ライブラリ関数(Math.sqrt)の使い方を総合的に習得する。

前提知識の確認

以下の内容を理解していることを確認すること。

Heronの公式

3辺の長さを a, b, c、面積を A とすると、以下の式が成り立つ。

s = (a + b + c) / 2
A = √(s × (s - a) × (s - b) × (s - c))

s は半周長(三角形の周長の半分)である。

参考:例題1のソースコード

以下は底辺と高さから三角形の面積を求めるプログラムである。演習ではこのプログラムを土台として使用する。

import java.lang.Math;
import java.util.Scanner;

public class Main
{
    public static void main(String[] args) {
        double teihen, takasa, menseki;
        Scanner s = new Scanner(System.in);

        System.out.println("Please Enter teihen =");
        teihen = s.nextDouble();
        System.out.println("Please Enter takasa =");
        takasa = s.nextDouble();

        menseki = teihen * takasa * 0.5;

        System.out.printf("menseki = %8.3f\n", menseki);
    }
}

手順

  1. Online GDB(https://www.onlinegdb.com)にアクセスし、言語を「Java」に設定する。
  2. 必要な変数を決定する。
    • 入力:a, b, c(3辺の長さ)
    • 計算:s(半周長)
    • 出力:A(面積)
  3. 例題1のプログラムを土台として使用する。クラス定義とmainメソッドの構造はそのまま流用できる。
  4. 以下の処理を順に記述する。
    • import文:java.lang.Mathとjava.util.Scanner
    • 変数宣言:a, b, c, s, Aをdouble型で宣言
    • Scannerオブジェクトの生成
    • a, b, cの入力:メッセージ表示とnextDoubleによる読み込み
    • sの計算:s = (a + b + c) / 2;
    • Aの計算:A = Math.sqrt(s * (s - a) * (s - b) * (s - c));
    • Aの出力:System.out.printfを使用
  5. プログラムを実行し、テスト用の値で検証する。

ヒント

テスト用の値:3辺が3, 4, 5の直角三角形では、面積は6.0になる。底辺3、高さ4として3×4÷2=6で検算できる。

よくある間違い

3. 条件分岐とプログラム制御:Javaプログラムの基本構造

資料(スライド):ji-3. 条件分岐とプログラム制御:Javaプログラムの基本構造 [PDF], [パワーポイント]

演習パート(クリックして展開)

学習の準備:Online GDB の使用

本演習では、オンライン開発環境 Online GDB を使用してJavaプログラムを実行する。

  1. ウェブブラウザを起動する
  2. https://www.onlinegdb.com を開く
  3. 画面上部の「Language」で「Java」を選択する
  4. エディタ画面にプログラムを入力し、「Run」ボタンで実行する

注意:Online GDB はオンラインサービスであるため、秘密にしたいプログラムの取り扱いには注意が必要である。

演習(1):2次方程式の改良

目的

例題3のプログラムは a≠0 を前提としている。a=0 の場合も正しく処理できるよう条件分岐を追加し、多分岐と論理演算の理解を深める。

例題3のプログラム(ベースコード)

import java.lang.Math;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        double a, b, c, D;
        Scanner s = new Scanner(System.in);
        System.out.println("Please Enter a =");
        a = s.nextDouble();
        System.out.println("Please Enter b =");
        b = s.nextDouble();
        System.out.println("Please Enter c =");
        c = s.nextDouble();
        D = b * b - 4 * a * c;
        if (D > 0) {
            System.out.printf("x = %8.3f, %8.3f\n",
                (-b + Math.sqrt(D)) / (2 * a),
                (-b - Math.sqrt(D)) / (2 * a));
        } else if (D == 0) {
            System.out.printf("x = %8.3f\n", -b / (2*a));
        } else {
            System.out.printf("x = %8.3f + %8.3f i, %8.3f - %8.3f i\n",
                -b / (2 * a), Math.sqrt(-D) / (2 * a),
                -b / (2 * a), Math.sqrt(-D) / (2 * a));
        }
    }
}

手順

  1. 上記のプログラムをOnline GDBのエディタにコピーする
  2. a=0 の場合に発生する問題を考察する
  3. a=0 のときに必要な場合分けを確認する
    • a=0 かつ b=0 かつ c=0 のとき
    • a=0 かつ b=0 かつ c≠0 のとき
    • a=0 かつ b≠0 のとき
  4. 手順3の各場合に対応する条件式を、論理演算(&&, !=)を用いて作成する
  5. 判別式Dによる分岐の前に、手順4で作成した条件分岐を追加する
  6. a=0 かつ b≠0 の場合の処理を実装する
  7. 以下のテストケースで動作を確認する
    • a=1, b=-3, c=2(通常の2次方程式)
    • a=0, b=2, c=-4(1次方程式)
    • a=0, b=0, c=5(解なし)
    • a=0, b=0, c=0(すべてのxが解)

ヒント

条件分岐の順序に注意する。判別式Dによる分岐を先に行うと、a=0 のときに0での除算が発生する。a=0 に関する条件を先に判定することで、この問題を回避できる。

条件式は (a == 0) && (b == 0) の形式で記述する。「等しくない」は != で表現する。

演習(2):平面と原点の距離

目的

例題4の直線と原点の距離を3次元の平面に拡張する。数学的公式のプログラムへの変換と、条件分岐による例外処理を学ぶ。

例題4のプログラム(ベースコード)

import java.lang.Math;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        double a, b, c, d;
        Scanner s = new Scanner(System.in);
        System.out.println("Please Enter a =");
        a = s.nextDouble();
        System.out.println("Please Enter b =");
        b = s.nextDouble();
        System.out.println("Please Enter c =");
        c = s.nextDouble();
        if ((a == 0) && (b == 0)) {
            System.out.println("a=0 and b=0!");
        } else {
            d = Math.abs(c) / Math.sqrt(a * a + b * b);
            System.out.printf("d = %8.3f\n", d);
        }
    }
}

距離の公式

直線 ax + by + c = 0 と原点の距離:

d = |c| / √(a² + b²)

平面 ax + by + cz + d = 0 と原点の距離:

距離 = |d| / √(a² + b² + c²)

手順

  1. 上記のプログラムをOnline GDBのエディタにコピーする
  2. 距離の公式を確認し、直線から平面への拡張を理解する
  3. 変数を追加する:zの係数cと定数項d
  4. 入力部分を修正し、a, b, c, d の4つの値を読み込むようにする
  5. 計算式を平面の距離公式に書き換える
  6. 条件分岐を修正する:a=0 かつ b=0 かつ c=0 のときは計算を行わない
  7. 以下のテストケースで動作を確認する
    • a=1, b=0, c=0, d=5(x軸に垂直な平面)
    • a=1, b=1, c=1, d=3(一般的な平面)
    • a=0, b=0, c=0, d=1(不正な入力)

ヒント

変数名の衝突に注意する。ベースコードでは「c」が定数項、「d」が距離を表している。平面では係数が1つ増えるため、変数名を整理する必要がある。例えば、定数項をd0、距離をdistとする方法がある。

条件式は (a == 0) && (b == 0)(a == 0) && (b == 0) && (c == 0) に拡張する。

4. Javaプログラミングにおける基本データ型と数値計算の基礎

資料(スライド):ji-4. Javaプログラミングにおける基本データ型と数値計算の基礎 [PDF], [パワーポイント]

演習パート(クリックして展開)

学習の準備:Online GDB の使用

本演習では、オンライン開発環境 Online GDB を使用してJavaプログラムを実行する。

  1. ウェブブラウザを起動する
  2. https://www.onlinegdb.com を開く
  3. 画面上部の「Language」で「Java」を選択する
  4. エディタ画面にプログラムを入力し、「Run」ボタンで実行する

注意:Online GDB はオンラインサービスであるため、秘密にしたいプログラムの取り扱いには注意が必要である。

演習:時間の換算

目的

整数の除算(/)と剰余(%)を組み合わせて、秒数を時・分・秒に変換する。例題1の金種計算と同じ考え方を用いる。

手順

  1. Online GDB(https://www.onlinegdb.com)にアクセスし、言語として「Java」を選択する。

  2. 入出力仕様を確認する。

    • 入力:秒数 x(整数)
    • 出力:h 時、m 分、s 秒
  3. プログラムの基本構造を入力する。

    import java.util.Scanner;
    
    public class Main {
        public static void main(String[] args) {
            int x, h, m, s;
            Scanner sc = new Scanner(System.in);
    
            // ここに処理を記述する
    
        }
    }
  4. キーボードから秒数 x を読み込む処理を追加する。

            System.out.println("Please Enter x (seconds) =");
            x = sc.nextInt();
  5. 時間の換算に必要な関係を確認する。

    • 1時間 = 3600秒
    • 1分 = 60秒
  6. 金種計算の考え方を適用し、h、m、s を求める計算式を記述する。金種計算では大きい単位(500円)から順に枚数を求めた。時間の換算でも同様に、時→分→秒の順に求める。

    • h:x を 3600 で割った商
    • m:x から時の分を除いた残りを 60 で割った商
    • s:x を 60 で割った余り
            h = x / 3600;
            m = (x % 3600) / 60;
            s = x % 60;
  7. 計算結果を画面に表示する処理を記述する。

            System.out.printf("%d h %d m %d s\n", h, m, s);
  8. 完成したプログラムを以下に示す。

    import java.util.Scanner;
    
    public class Main {
        public static void main(String[] args) {
            int x, h, m, s;
            Scanner sc = new Scanner(System.in);
    
            System.out.println("Please Enter x (seconds) =");
            x = sc.nextInt();
    
            h = x / 3600;
            m = (x % 3600) / 60;
            s = x % 60;
    
            System.out.printf("%d h %d m %d s\n", h, m, s);
        }
    }
  9. プログラムを実行し、x=3723 を入力して以下の出力を確認する。

    Please Enter x (seconds) =
    3723
    1 h 2 m 3 s

ヒント

5. Javaプログラミングにおける繰り返し処理と数値計算の基礎

資料(スライド):ji-5. Javaプログラミングにおける繰り返し処理と数値計算の基礎 [PDF], [パワーポイント]

演習パート(クリックして展開)

学習の準備:Online GDB の使用

本演習では、オンライン開発環境 Online GDB を使用してJavaプログラムを実行する。

  1. ウェブブラウザを起動する
  2. https://www.onlinegdb.com を開く
  3. 画面上部の「Language」で「Java」を選択する
  4. エディタ画面にプログラムを入力し、「Run」ボタンで実行する

注意:Online GDB はオンラインサービスであるため、秘密にしたいプログラムの取り扱いには注意が必要である。

例題1〜3ではwhile文の基本と応用を学び、例題4ではfor文と二重ループを学ぶ。例題5では繰り返し計算における誤差の累積を確認する。

例題1:自然数の和

整数Nを読み込み、1からNまでの和を求める。while文の基本的な使い方を学ぶ。

while文とは

while文は、条件式が真である限り処理を繰り返す制御構造である。繰り返しのたびに条件式が評価され、真であれば処理が実行される。偽になると繰り返しが終了する。

ソースコード

import java.util.Scanner;

public class Main
{
    public static void main(String[] args) {
        int N, sum, i;
        Scanner s = new Scanner(System.in);
        System.out.println("Please Enter N =");
        N = s.nextInt();
        sum = 0;
        i = 1;
        while(i <= N) {
            sum = sum + i;
            i = i + 1;
        }
        System.out.printf("goukei = %d\n", sum);
    }
}

動作の理解

N = 7 の場合、繰り返しは以下のように進む。

各回で sum には「1からiまでの和」が格納される。繰り返し終了時、sum には1からNまでの和が格納されている。

例題2:最大公約数の計算

2つの整数m, nを読み込み、最大公約数を求める。ユークリッドの互除法を用いる。

ユークリッドの互除法とは

最大公約数を効率的に求める手続きである。m, n(m ≧ n)について以下の規則を適用する。

この規則を余りが 0 になるまで繰り返す。

ソースコード

import java.util.Scanner;

public class Main
{
    public static void main(String[] args) {
        int m, n, r;
        Scanner s = new Scanner(System.in);
        System.out.println("Please Enter m =");
        m = s.nextInt();
        System.out.println("Please Enter n =");
        n = s.nextInt();
        r = m % n;
        while(r > 0) {
            m = n;
            n = r;
            r = m % n;
        }
        System.out.printf("GCD = %d\n", n);
    }
}

動作の理解

m = 80, n = 35 の場合を追跡する。最初の r = m % n で r = 10 となる。

繰り返しのたびに扱う数が小さくなり、最終的に余りが 0 になった時点の n が最大公約数となる。

例題3:総和と平均

データを1つずつ読み込み、合計と平均を求める。負の数が入力されたら終了する。データ件数が事前に決まっていない場合の繰り返し処理を学ぶ。

ソースコード

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int sum, i, x;
        sum = 0;
        i = 0;
        Scanner s = new Scanner(System.in);
        System.out.printf("Please Enter x[%d] =", i);
        x = s.nextInt();
        while(0 <= x) {
            sum = sum + x;
            i = i + 1;
            System.out.printf("Please Enter x[%d] =", i);
            x = s.nextInt();
        }
        System.out.printf("sum = %d\n", sum);
        System.out.printf("%d / %d = %d", sum, i, sum / i);
    }
}

動作の理解

入力が 1, 2, 3, -1 の場合を追跡する。

結果として sum = 6, i = 3 となり、平均は 6 / 3 = 2 と計算される。

例題4:九九の表

九九の表を表示する。for文と繰り返しの入れ子(二重ループ)を学ぶ。

for文とは

for文は、ループカウンタの初期化、条件式、更新処理を一行にまとめた構文である。決まった回数の繰り返しを簡潔に書ける。

for(初期化; 条件式; 更新) {
    繰り返す処理
}

例えば for(i = 1; i <= 9; i++) は、i を 1 から 9 まで 1 ずつ増やしながら繰り返すことを意味する。while文で書くと以下と同等である。

i = 1;
while(i <= 9) {
    繰り返す処理
    i++;
}

ソースコード

public class Main
{
    public static void main(String[] args) {
        int i, j;
        for(i = 1; i <= 9; i++) {
            System.out.printf("%3d:", i);
            for(j = 1; j <= 9; j++) {
                System.out.printf("%3d", i * j);
            }
            System.out.println("");
        }
    }
}

動作の理解

外側のfor文で i が 1 から 9 まで変化する。各 i の値に対して、内側のfor文で j が 1 から 9 まで変化し、i × j を出力する。

外側のループが1回進むごとに内側のループが9回実行されるため、合計 9 × 9 = 81 回の掛け算が行われる。

例題5:ド・モアブルの定理と計算誤差

複素数の累乗を繰り返し計算し、理論値と比較する。繰り返し計算における誤差の累積を学ぶ。

ド・モアブルの定理

複素数について以下の等式が成り立つ。

(cosθ + i sinθ)n = cos nθ + i sin nθ

ここで i は虚数単位である。

複素数の積

z1 = x1 + iy1、z2 = x2 + iy2 のとき、積 z1 × z2 は以下のように計算される。

ソースコード

import java.lang.Math;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int n, j;
        double x1, y1, x2, y2, theta, temp;
        Scanner s = new Scanner(System.in);
        System.out.println("Please Enter n =");
        n = s.nextInt();
        System.out.println("Please Enter theta =");
        theta = s.nextDouble();
        x1 = Math.cos(theta);
        y1 = Math.sin(theta);
        x2 = x1;
        y2 = y1;
        j = 1;
        while(j <= n) {
            System.out.printf("(cos theta + i sin theta)%d = %8.3f + i%8.3f\n", j, x1, y1);
            System.out.printf("cos %d theta + i sin %d theta = %8.3f + i %8.3f\n", j, j, Math.cos(j * theta), Math.sin(j * theta));
            temp = x1 * x2 - y1 * y2;
            y1 = x1 * y2 + x2 * y1;
            x1 = temp;
            j = j + 1;
        }
    }
}

動作の理解

このプログラムは2種類の値を出力する。

ド・モアブルの定理により、両者は一致するはずである。しかし、繰り返し計算では各ステップで小さな誤差が生じ、それが累積していく。n が大きくなるほど、繰り返し計算の結果と理論値の差が広がることを確認できる。

演習:m から n までの和

目的

while文を用いた繰り返し処理の応用として、任意の範囲の整数の和を計算するプログラムを作成する。

課題

2つの整数データ(M, N)を読み込んで、MからNまでの和を求めるプログラムを作成しなさい。

実施手順

  1. Online GDB を開き、言語を Java に設定する
  2. 例題1のプログラムを確認し、while文の構造を復習する
  3. 例題1との違いを分析する
    • 例題1:開始値が 1 に固定
    • 本演習:開始値が M(ユーザ入力)
  4. プログラムを設計する
    • 必要な変数を決定する
    • ループカウンタの初期値と終了条件を決定する
  5. プログラムを作成し、Online GDB で実行する
  6. 動作を確認する(例:M = 3, N = 7 のとき、3 + 4 + 5 + 6 + 7 = 25)

ヒント

発展課題(任意)

M > N の場合にも対応できるプログラムへの拡張を考えてみよ。

6. Javaプログラミングにおける配列と数値計算アルゴリズムの基礎

資料(スライド):ji-6. Javaプログラミングにおける配列と数値計算アルゴリズムの基礎 [PDF], [パワーポイント]

演習パート(クリックして展開)

学習の準備:Online GDB の使用

本演習では、オンライン開発環境 Online GDB を使用してJavaプログラムを実行する。

  1. ウェブブラウザを起動する
  2. https://www.onlinegdb.com を開く
  3. 画面上部の「Language」で「Java」を選択する
  4. エディタ画面にプログラムを入力し、「Run」ボタンで実行する

注意:Online GDB はオンラインサービスであるため、秘密にしたいプログラムの取り扱いには注意が必要である。

配列の基礎知識

配列とは

配列とは、同じ型のデータを並べて格納し、各要素に番号(添字、英語ではindex)を付けて管理するデータ構造である。添字は0から始まる。

配列の宣言

配列を使うには、名前、型(データの種類)、サイズを指定して宣言する必要がある。

配列の読み書き

配列の要素にアクセスするには、配列名と添字を指定する。たとえば、num[3]は配列numの添字3の要素を指す。

// 配列の宣言と初期化
int num[] = {10, 20, 30, 40};

// 配列からの読み出し
int x = num[2];  // xに30が代入される

// 配列への書き込み
num[0] = 100;    // num[0]が100に変わる

例題1:月の日数

目的

配列の宣言、初期化、および値の読み出しを実装できるようになる。

課題内容

年と月を読み込み、その月の日数を求めるプログラムを作成する。うるう年の2月は29日とする。

実施手順

  1. Online GDBを開き、Javaを選択する
  2. 以下のプログラムを入力する
  3. 実行ボタンを押し、年と月を入力して結果を確認する
  4. 異なる年月(2024年2月、2023年2月、2021年11月など)で動作を確認する

ソースコード

import java.util.Scanner;

public class Main
{
    public static void main(String[] args) {
        int y, m;
        // 添字0から12までを使用(添字と月を一致させるため添字0には0を格納)
        int num[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

        Scanner s = new Scanner(System.in);

        System.out.println("Please Enter y(year) =");
        y = s.nextInt();  // 年の読み込み

        System.out.println("Please Enter m(month) =");
        m = s.nextInt();  // 月の読み込み

        // うるう年の2月かどうかを判定
        if ((m == 2) && (((y % 400) == 0) || (((y % 100) != 0) && ((y % 4) == 0)))) {
            System.out.printf("number of days %d/%d is 29\n", y, m);
        } else {
            System.out.printf("number of days %d/%d is %d\n", y, m, num[m]);  // 配列からの読み出し
        }
    }
}

ポイント


例題2:ベクトルの内積

目的

for文と配列を組み合わせて、繰り返し計算を実装できるようになる。

背景知識:内積の計算

2つのベクトル a = (a0, a1, a2) と b = (b0, b1, b2) の内積は、次の式で計算する。

a・b = a0×b0 + a1×b1 + a2×b2

課題内容

ベクトル (1.9, 2.8, 3.7) とベクトル (4.6, 5.5, 6.4) の内積を計算し、表示するプログラムを作成する。

実施手順

  1. Online GDBを開き、Javaを選択する
  2. 以下のプログラムを入力する
  3. 実行ボタンを押し、結果を確認する
  4. ベクトルの値を変更して、異なる内積を計算する

ソースコード

public class Main {
    public static void main(String[] args) {
        double p;
        int i;
        double u[] = {1.9, 2.8, 3.7};  // ベクトルuの初期化
        double v[] = {4.6, 5.5, 6.4};  // ベクトルvの初期化

        p = 0;  // 内積の累積値を初期化
        for(i = 0; i <= 2; i++) {
            p = p + (u[i] * v[i]);  // 各成分の積を累積
        }
        System.out.printf("p(product) = %f\n", p);
    }
}

ポイント

動作の確認

繰り返しiの値条件判定pの値の変化
1回目00 <= 2 成立p = 0 + 1.9×4.6
2回目11 <= 2 成立p = p + 2.8×5.5
3回目22 <= 2 成立p = p + 3.7×6.4
4回目33 <= 2 不成立ループ終了

例題3:棒グラフを描く

目的

ループの入れ子(二重ループ)と配列を組み合わせたプログラムを実装できるようになる。

課題内容

整数の配列から、その値に応じた長さの棒グラフを「*」で表示するプログラムを作成する。

実施手順

  1. Online GDBを開き、Javaを選択する
  2. 以下のプログラムを入力する
  3. 実行ボタンを押し、結果を確認する
  4. 配列aの値を変更して、異なる棒グラフを表示する

ソースコード

public class Main {
    public static void main(String[] args) {
        int i, j;
        int a[] = {6, 4, 7, 1, 5, 3, 2};  // 棒グラフの長さを格納

        for(i = 0; i < 7; i++) {          // 各要素について
            for(j = 1; j <= a[i]; j++) {  // a[i]回だけ繰り返す
                System.out.printf("*");
            }
            System.out.printf("\n");       // 改行
        }
    }
}

ポイント


例題4:Horner法による多項式の計算

目的

Horner法の原理を理解し、while文と配列を使って多項式計算を実装できるようになる。

背景知識:Horner法

n次の多項式 f(x) = a0 + a1・x + a2・x² + ... + an・xⁿ を計算する際、各項を個別に計算すると乗算回数が多くなる。Horner法は、多項式を次のように変形することで効率的に計算する。

f(x) = a0 + (a1 + (a2 + ... + (an-1 + an・x)x...)x)x

たとえば、5 + 6x + 3x² は 5 + (6 + 3x)x と変形できる。

計算手順は次のとおりである。

  1. anから開始
  2. an-1 + an・x を計算
  3. an-2 + (前の結果)・x を計算
  4. a0まで繰り返す

課題内容

次数nと係数a0からan、およびxの値を読み込み、f(x)を計算するプログラムを作成する。

実施手順

  1. Online GDBを開き、Javaを選択する
  2. 以下のプログラムを入力する
  3. 実行ボタンを押す
  4. 次数n、係数a[0]からa[n]、xの値を順に入力する
  5. 結果を手計算と比較して確認する

ソースコード

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int i, n;
        double x, y;
        double a[] = new double[20];  // 係数を格納する配列

        Scanner s = new Scanner(System.in);

        System.out.println("Please Enter n =");
        n = s.nextInt();  // 次数の読み込み

        for(i = 0; i <= n; i++) {
            System.out.printf("Please Enter a[%d] =\n", i);
            a[i] = s.nextFloat();  // 係数の読み込み
        }

        System.out.println("Please Enter x =");
        x = s.nextFloat();  // xの値の読み込み

        // Horner法による計算
        y = a[n];           // 最高次の係数から開始
        i = n - 1;
        while(i >= 0) {
            y = y * x + a[i];  // Horner法の核心
            i = i - 1;
        }

        System.out.printf("y = %8.3f", y);
    }
}

ポイント

動作の確認例

n=2、a[0]=5、a[1]=6、a[2]=3、x=2 を入力した場合:

5 + 6×2 + 3×2² = 5 + 12 + 12 = 29 が計算される。


例題5:エラトステネスのふるい

目的

エラトステネスのふるいの原理を理解し、配列とwhile文の入れ子を使って素数探索を実装できるようになる。

背景知識:エラトステネスのふるい

エラトステネスのふるいは、古代ギリシャの数学者エラトステネスが考案した素数を見つけるアルゴリズムである。2からmaxまでの整数について、以下の手順で素数を見つける。

  1. 2からmaxまでのすべての数を「素数候補」とする
  2. 2の倍数(4, 6, 8, ...)を消す(2自身は残す)
  3. 次に残っている数(3)の倍数を消す
  4. 次に残っている数(5)の倍数を消す(4はすでに消えている)
  5. √maxまでこの操作を繰り返す
  6. 残った数がすべて素数である

√maxまで調べれば十分な理由:合成数(素数でない数)は必ず√max以下の約数を持つためである。

課題内容

指定した範囲内の素数をすべて求め、表示するプログラムを作成する。

実施手順

  1. Online GDBを開き、Javaを選択する
  2. 以下のプログラムを入力する
  3. 実行ボタンを押す
  4. maxの値(例:100)を入力する
  5. 表示された素数の一覧を確認する

ソースコード

import java.lang.Math;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int i, n, max;
        int p[] = new int[100000];  // 素数判定用の配列

        Scanner s = new Scanner(System.in);

        System.out.println("Please Enter max =");
        max = s.nextInt();

        // すべての数を素数候補(1)で初期化
        for(i = 1; i <= max; i++) {
            p[i] = 1;
        }

        n = 2;  // 最小の素数から開始
        while(n <= Math.sqrt(max)) {
            // nの倍数を消す(素数でないと判定)
            i = 2;
            while((n * i) <= max) {
                p[n * i] = 0;  // nの倍数は素数でない
                i = i + 1;
            }
            // 次の素数を探す
            n = n + 1;
            while((p[n] == 0) && (n <= Math.sqrt(max))) {
                n = n + 1;  // すでに消えている数はスキップ
            }
        }

        // 素数の表示
        for(i = 2; i <= max; i++) {
            if(p[i] == 1) {
                System.out.printf("%d, ", i);
            }
        }
    }
}

ポイント


まとめ

本演習では、以下の内容を学習した。

  1. 配列の基礎:データの並びに添字を付けて管理する仕組み、整数型・浮動小数型の配列宣言と読み書き
  2. 配列と繰り返しの組み合わせ:for文・while文による配列要素の順次処理
  3. 数値計算アルゴリズム:Horner法による多項式計算、エラトステネスのふるいによる素数探索

配列と繰り返し文の組み合わせは、大量データを効率的に処理するための基本である。