学習10日目:アルゴリズムをJavaで。

今日の学習時間。

  • Day:10
  • Today:7h
  • Total:74h

学習内容について。

RPGで魔法攻撃(インターフェイス)を実装してみる。

package test;

public interface MagicAttack {
    public abstract void magic_attack(Character opponent);
}

全部のキャラクターが魔法攻撃を使えるわけではないのでCharacterクラスではなく、インターフェイスを使ってHeroクラスに実装した。

抽象クラスかインターフェイスのどちらを使うか迷うところだが、今回は「has-a」の関係性なのでインターフェイスを使うべきである(「is-a」の関係性の場合は抽象クラス・メソッドを使用する)。

  1. MagicAttack インターフェイスを作成
  2. MagicAttack を定義
  3. Hero クラスに MagicAttack を implementsさせる
  4. magic_attack() メソッドの定義を記述(@Override
  5. RPG クラスのメインメソッドで magic_attack() を実行

RPGゲームを1つ完成させるのには途方もない時間がかかるね。。「RPGツクール」とかいう便利なツールもあるらしいし、もし自分で作るならJavaでは絶対作らない。下記のサイトが面白かった(JavaではなくC言語ですが)。アルゴリズムの作り方とか参考になる。

プロ野球チームの勝ち負け数を管理できるプログラムを作成。

条件
  • 勝ち負け数を管理するためのクラスを作成
  • インスタンスを6チーム分生成した後に各チームの勝ち負け数を表示
  • カプセル化を使う
package task;

class BaseBallTeam {
    private String name;
    private Integer win;
    private Integer lose;
    private Integer draw;

    public BaseBallTeam() {
    }

    public BaseBallTeam(String name, Integer win, Integer lose, Integer draw) {
        this.name = name;
        this.win = win;
        this.lose = lose;
        this.draw = draw;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getWin() {
        return this.win;
    }

    public void setWin(Integer win) {
        this.win = win;
    }

    public Integer getLose() {
        return this.lose;
    }

    public void setLose(Integer lose) {
        this.lose = lose;
    }

    public Integer getDraw() {
        return this.draw;
    }

    public void setDraw(Integer draw) {
        this.draw = draw;
    }

    public double getRate() {
        return (double) this.win / (this.win + this.lose);
    }

    public void report() {
        System.out.println(this.name + "の2019年の成績は" + this.win + "勝" + this.lose + "敗" + this.draw + "分、勝率は" + getRate() + "です。");
    }
}
  1. BaseBallTeam クラスを作成
  2. カプセル化を使ったプロパティを作成
  3. それぞれのゲッターとセッターを用意
  4. 勝率を計算するgetRate メソッドを作成
  5. 実行結果を表示するreportメソッドを作成
  6. メインメソッドの入っているクラスを用意
  7. BaseBallTeam のインスタンスを6個生成
  8. report メソッドを呼び出して、勝敗情報を表示

基本的なアルゴリズム。

  • 選択法
    • 「ある要素」と「それ以外の要素」を次々に比較
  • 交換法
    • 最後尾の2要素から次々に「隣同士の比較」
  • 挿入法
    • 新しいリストの末尾に既存のリストの要素を挿入
    • 最後尾の要素と挿入した要素を比較
import java.util.Arrays;

class SelectionSort {
    public static void main(String[] args) {
        int[] nums = new int[] { 8, 4, 6, 2, 7, 3, 5, 1, 9 };

        for (int i = 0; i < nums.length - 1; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] > nums[j]) {
                    int temp = nums[i];
                    nums[i] = nums[j];
                    nums[j] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(nums));
    }
}

/* 実行結果

[1, 2, 3, 4, 5, 6, 7, 8, 9]

*/
並び替えのアルゴリズム一例
  • シェルソート
    • 間隔の離れた要素の組に対してソートを行い、だんだんと比較する要素間の間隔を小さくしながらソートを繰り返す
    • 単純に近くの要素を比較する場合よりも速く、要素を所定の位置に移動させられる
  • クイックソート
    • 実用上もっとも高速な並べ替えアルゴリズム
    • ピボットと呼ぶ要素を軸に分割を繰り返して整列を行う
      • 分割統治法
  • マージソート
    • 並べ替えたい配列を再帰的に分割していき、再び併合して並び替えるアルゴリズム
検索のアルゴリズム一例
  • 線形探索
    • リストや配列に入ったデータに対する検索する際に先頭から順に比較を行い、それが見つかれば終了
  • 二分探索(バイナリサーチ)
    • 中央の値を見て、検索したい値との大小関係を用いて、検索したい値が中央の値の右にあるか、左にあるかを判断して、片側には存在しないことを確かめながら検索
    • 未ソートのリストや大小関係の定義されない要素を含むリストには使用不可
  • 木構造
    • 木が幹から枝、枝から葉に分岐していくデータ構造
    • マインドマップみたいな感じ
  • 動的計画法
    • 対象となる問題を複数の部分問題に分割し、部分問題の計算結果を記録しながら解いていく手法
    • 特定のアルゴリズムを指すのではなく、上記のような手法を使うアルゴリズムの総称

アルゴリズムは完全に数学の知識が必要になると実感。高校数学から勉強し直したほうが、理解は深まる気がする。ソートの説明は曖昧だけど、ウィキペディアにあるGIF画像の例が分かりやすかったのでオススメ。

「エラトステネスのふるい」をJavaで。

エラトステネスのふるい
  • 1から100までの連続する整数から、素数を選び出す
  • 素数とは、自明な正の因数(1 と自分自身)以外に因数を持たない自然数
    • 1は素数に入れない
    • 2を除いた2の倍数は素数ではない
    • 3を除いた3の倍数は素数ではない
    • 5を除いた5の倍数は素数ではない
    • 7を除いた7の倍数は素数ではない

「標準入力」

標準入力とはJavaのプログラム内で「キーボードから入力された情報を受け取る」ために使う機能のこと。

  • Scanner=標準入力を使うために必要なクラス
    • java.util.Scanner を import
  • Scanner の nextLine() を実行した時点でキーボードからの入力を待つ状態に
    • 入力後にリターンを押すと、プログラムに文字列が送られる
  • 最後にScanner の close() を実行

コンソールにnextLine()の名前を入力する必要がある。実際、私はそのことを理解するのに30分はかかってしまった。YouTubeで調べたけど、分からない箇所は動画の方がいいかもね。

import java.util.Scanner;

public class InputSample {

    public static void main(String[] args) {     
        Scanner scanner = new Scanner(System.in);
        System.out.println("名前を入力してください:");
        String name = scanner.nextLine();        
        System.out.println("こんにちは、" + name + "さん!");
     
        scanner.close();
    }
}

/* 実行結果

名前を入力してください:
きき
こんにちは、ききさん!

*/

数値の場合はnextLine() で受け取った後にint型へ変換するか nextInt() のような別のメソッドを実行。

今日の反省と明日の目標。

今日は実際に使えそうなプログラムを作成できたので楽しかった。やっぱり、覚えるばかりだと正直きついところはあるよね。Javaの学習を始めてから10日目だけど、起きている間は、ほぼパソコンの画面を見ているから慢性的に目が疲れてきた。多分、12時間はブルーライトを浴びてると思う。ちょっと息抜きもしたくなってきた今日この頃です。

明日はデータベース(MySQL)について学習していく予定です。

閉じる