コンピュータ基礎および演習II

演習問題

解答は

に提出しなさい。クラスファイル (〜.class) は提出しなくてよい。 提出には gFTP 等の ftp ソフトを用いること。

問題1

前回、円柱(cylinder)の体積と表面積を、 円クラスや長方形クラスを用いて求めた。 今回は、底面(上面と下面)の形状が正方形(square; regular quadrangle) と楕円(ellipse)の場合、 つまり、正四角柱(regular quadrangular prism)、 楕円柱(elliptic cylinder)の体積を考える。

楕円と円、 長方形と正方形の関係を考慮しつつ、 正四角柱、楕円柱の体積を表示するプログラムを作成しなさい。 ファイル名は VolumeAndSurfaceArea.java とする。

楕円に関する公式

ただし、a は楕円の長軸半径(major axis)、b は短軸半径(minor axis)で、図で表現すると下図の通り。

実数 x の平方根(square root) は Math.sqrt(x) とすると求まる (が、表面積は求めなくてよい)。

問題2

あなたはこの冬休み、夏のPC組み立てを受講したかは関係なく、自分のこだわりのパソコンを組むことにした。思い入れがあるので名前だけはすぐにきまったものの、どんなパーツ(部品)を買ってくるかまだ考えていない。

問題2-1

まず方針だけでも立てようと思い、以下の表を作成してみた。

パーツスペック
ケースアルミケース
電源Pentium4対応電源
メインボードPentium4用メインボード
CPUタイプPentium4
メモリ512MB
ハードディスク250GB
キーボード日本語キーボード
マウスホイールマウス

この表の各行にある2つの項目(例えば「ケース - アルミケース」)の関係をそれぞれ説明しなさい。 ファイル名は Q2.txt とする。

注意: 「ケース」は「ケースの種類」が省略されたものである、 「メモリ」は「メモリの容量」が省略されたものである、 などと表現の「省略」を認める深読みをすると解釈が変わってくるが、 説明が矛盾していなければどのように解釈してもよい。

問題2-2

CPU、メモリ(main memory)、ハードディスク(hard disk drive) はメインボード(main board)に接続するため、 メインボードと CPU、メインボードとメモリ、メインボードとハードディスクは has-a の関係とする。 また、電源(power supply)とメインボードはケース内部に取りつけるため、 ケース(PC case)と電源、ケースとメインボードは has-a の関係とする。 そして、パソコン(PC) はケースとキーボード(keyboard) とマウス(mouse) からなるものとする。 それぞれをクラスとしたときのクラス定義を書きなさい。 (has-a の関係が表現できていればよい)

解答は次の問題2-3の PCBuilder.java の中に記述してもよい。

問題2-3

市販ソフトのパッケージには、 そのソフトを動作させるのに必要な推奨スペックが示されている。 パソコンにその要求されたスペック値を与えると、 ソフトが動作可能かどうか判定するメソッドを作成しなさい。

ファイル名は PCBuilder.java とする。 クラス PCBuilder は例えば以下のようになる。

class PCBuilder {
    public static void main(String[] args) {
	PC pc = new PC(512, 250);                 // メモリ512MB, HDD 250GB
	
	if(pc.satisfiesSpecs(256, 80) == true) {  // メモリ256MB, HDD 80GB
	    System.out.println("このソフトは動作します。");
	}
    }
}

この例では、 satisfiesSpecs(必要とするメモリ容量, 必要とするディスク容量) というメソッドを用意している。 その条件が満たされていれば true を返すメソッドである。

問題3

あなたはこの冬休み、念願の車の購入に踏み切ることにした。信号が青に変わった時に先頭で飛び出さなければ気が済まない性格なため、加速最優先で車選びをすることにした(予算の範囲内で)。

問題3-1

車は数多くの部品から成り立っているが、ここでは大雑把に、 車(car)は車体(body)とエンジン(engine)からなるものとする。 車クラス Car、車体クラス Body、エンジンクラス Engine を定義しなさい。 それぞれ、重量を求めるメソッド weight() を実装すること。 クラス Body のインスタンスの生成はクラス Car のコンストラクタ内で行なうこと。 クラス Engine のインスタンスは外部で生成し、クラス Car のインスタンスに渡すこと。

問題3-2

車の加速のよさを判断する際に参考になる指標として、 パワーウエイトレシオ(Power-to-Weight Ratio; 1馬力当たりの車重)がある。 エンジンの出力は kW または馬力(PS)で表すが、 馬力が大きくても車体が重ければ加速は鈍くなる。 1馬力当たりの車重が軽いほど、つまり、 パワーウエイトレシオの値が小さいほど加速がよいと判断できる。

クラス Engine に馬力を返すメソッド horsePower() を、 クラス Car にパワーウエイトレシオを返すメソッド powerToWeightRatio() を実装しなさい。

以下のように、エンジンを積み替えることができるようにすること。

class Driver {
    public static void main(String[] args) {
        Engine engine1 = new Engine(150, 300);  // 200ps, 300kg
        Engine engine2 = new Engine(180, 400);  // 180ps, 400kg
        Car car = new Car(1000);                // 1000kg (body)
	car.setEngine(engine1);
	System.out.println(
	    "エンジン1搭載時のパワーウエイトレシオ: " + car.powerToWeightRatio());
	car.setEngine(engine2);
	System.out.println(
	    "エンジン2搭載時のパワーウエイトレシオ: " + car.powerToWeightRatio());
}

この問題の提出ファイルのファイル名は Driver.java とする。

問題4

あなたは CD コレクションの枚数が増えすぎて、何を持っているのかも よくわからなくなってきたので、各 CD の情報をパソコンに入力して管理することにした。

問題4-1

例によってクラス CD を定義しなさい。 アーティスト名、タイトル名、ジャンルを文字列の属性として持つこと。 今回はトラックの情報は省略してかまわない。

問題4-2

クラス CD の配列の中から、希望の CD を探し出すことを考える。 配列の要素は無秩序に並んでいるとすると、 配列の先頭から順に希望の CD を探していくしかない。 そこでクラス CD に、引数で与えられた文字列がアーティスト名と一致するかどうかを調べるメソッド artistEquals(String s) を実装し、 配列の各要素でこのメソッドを利用することにより希望の CD を探し出す処理を記述しなさい。 artistEquals(String s) の戻り値の型は boolean とする。 mainのあるクラスのクラス名は MusicFreak とする。

問題4-3 (余力のある人のみ)

CD を、まずジャンルで大まかに分類し、 その各ジャンルで、アーティスト名の順(辞書順)に並べることにした。 ただし、同一アーティストの CD はタイトル名の順(辞書順)に並べることにした。

並べ替えを行なうには、任意の2つの要素について大小が求められる必要がある。 この場合、クラス CD のインスタンスを並べ替えることになるので、 任意の2つのインスタンス同士を比較して、その大小を返すメソッドが必要となる。 他のインスタンスとの大小を返すメソッド compareTo(Object obj) を実装しなさい。 引数は任意のインスタンスを意味する Object クラスのインスタンス、 戻り値は int 型とし、このインスタンスが比較対象のインスタンスよりも辞 書順で前に並べるべきであれば -1、等しければ 0、辞書順で後ろに並ぶべき ならば 1 を返すこととする。

なお、この compareTo(Object obj) を実装すると Comparable インタフェースを実装したことになるので、クラス定義は以下のようになる。

class CD implements Comparable {
    ...
    public int compareTo(Object obj) {
        CD targetCD = (CD)obj;
        ....
        // このクラスのインスタンスと、比較対象 targetCD との比較をする
        ....
    }
}

さらに、クラス CD の配列の名前を cds とすると、 Arrays.sort(cds) として並べ替えを行なうことができる。 MusicFreak クラスは次のようになる (ただし以下の例ではCDにアーティスト名しか登録してない)。

import java.util.Arrays;            // Arrays を使用する際に必要な記述

class MusicFreak {
    public static void main(String[] args) {
	CD[] cds = new CD[3];
	cds[0] = new CD("Radiohead");
	cds[1] = new CD("Belle & Sebastian");
	cds[2] = new CD("Spiritualized");
	Arrays.sort(cds);
	for(int i = 0; i < cds.length; i++)
	    System.out.println("CD No." + i + ": " + cds[i].getArtist());
    }
}