MikiTech

文系新卒エンジニアの学習記録

【基本情報】平成21年度秋 午後Javaを解く

問題

※あくまで復習を兼ねています。間違っていたらご指摘おねがいします。

www.fe-siken.com

コード

【プログラム1】

public class CellPhonePlan{
    private CallingPlan callingPlan;
    private PacketPlan packetPlan;

    CellPhonePlan(CallingPlan callingPlan, PacketPlan packetPlan){
        this.callingPlan = callingPlan;
        this.packetPlan = packetPlan;
    }

    public int calculateCharge(int minutes, int packages){
        return callingPlan.calculateCharge(minutes) + packetPlan.culculateCharge(packets);
    }

    public String getName(){
        return callingPlan.getName() + " " + packetPlan.getName();
    }
}

【プログラム2】

public class CallingPlan {
    private String name;
    private int basicCharge;
    private int included;
    private int callingRate;

    CallingPlan(String name, int basicCharge, int included, int callingRate){
        this.name = name;
        this.basicCharge = basicCharge;
        this.included = included;
        this.callingRate = callingRate;
    }

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

    public int calculateCharge(int minutes){
        int callingCharge = 問題A;
        if(問題B){
            callingCharge = 0;
        }
        return basicCharge + callingCharge;
    }
}

【プログラム3】

public interface PacketPlan {
    String getName();
    int culculateCharge(int packets);
}

問題AとBについて

問題A
ア:callingRate * minutes イ:callingRate * minutes - included ウ:included   
エ:included - callingRate * minutes1
 問題B
ア:callingCharge < 0 イ:callingCharge < included ウ:callingCharge > 0 エ:callingCharge > included
   public int calculateCharge(int minutes){
        int callingCharge = 問題A;
        if(問題B){
            callingCharge = 0;
        }
        return basicCharge + callingCharge;
    }

問題AとBはcalculateChargeメソッドにあります。
そもそもcalculateChargeメソッドがあるCellPhonePlanクラスは料金プランを表す。

そしてcalculateChargeメソッドの説明を問題文からピックアップすると…

メソッド calculateCharge は,引数で渡された利用状況に対する料金を返す。

そもそもCellPhonePlanクラスに定義されているフィールドが料金プランの何を示しているかを問題文から読み解く必要があります。
f:id:Mikiyakupo:20200913014452p:plain フィールドは以下の通り。

   private int basicCharge;
    private int included;
    private int callingRate;

basicChargeは、基本料金っぽいですね。
callingRateは、通話が入っていてRateとあるため恐らく1分あたりの通話料金でしょう。
残ったincludedは無料通話分と言えます。(”含まれている”と書いてありますし…)

となると、後は日本語の理解の問題。
minutesは分であるため、これにcallingRateを掛けてどのくらい通話したのかを算出します。
無料通話分があるためこれを引けば良さそう。

よって問題Aの答えは
問題Bは、条件を記入する場所。
callingCharge = 0;を条件分岐内でしていることから、
通話料金に関する条件分岐していそうです。
先程、直前の問題Aで無料通話分を引いています。
その無料通話を超えない分、つまりcallingCharge < 0であるが正解。

【プログラム4】

public class Measured 問題C{
    private int packetRate;

    Measured(int packetRate){
        this.packetRate = packetRate;
    }

    public String getName(){return "";}

    public int calculateCharge(int packets){
        return packetRate * ((packets+ 99 )/100 );
    }
}

【プログラム5】

public class Tiered 問題C{
    private String name;
    private int basicCharge;
    private int allowance;
    private int packetRate;

    Tiered(String name, int basicCharge, int allowance, int packetRate){
        this.name = name;
        this.basicCharge = basicCharge;
        this.allowance = allowance;
        this.packetRate = packetRate;
    }

    public String getName(){return name;}

    public int calculateCharge(int packets){
        int charge = basicCharge;
        if(packets > allowance){
            charge += packetRate * ((問題D)/ 100);
        return charge;
        }
    }
}

問題Cについて

ア:extends CellPhonePlan イ:extends PacketPlan ウ:implements CellPhonePlan 
エ:implements PacketPlan

継承の問題。
メソッド見ると、抽象クラスのプログラム3を継承しているため、
implements PacketPlanのエが正解

問題Dについて

ア:allowance + 99 イ:packets + 99 ウ:packets + allowance + 99 
エ:packets - allowance + 99

Tieredクラスは、

パケット料金の割引サービスS1を表す。

とあります。
f:id:Mikiyakupo:20200913174419p:plain

10,000パケット超えた…という記載があるため、恐らくif文の条件に当たる部分でしょう。
問題Dを100で割っています。
パケットが10,000を超えたものを100で割って金額として加算しているため、この計算をする必要がありそうです。
そのため答えはエのpackets - allowance +99になります。

【プログラム6】


public class CellPhonePlanner {
    static final CallingPlan[] callingPlans = {
        new CallingPlan("A", 2000, 1000, 40),
        new CallingPlan("B", 3000, 2000, 30)
    };
    static final PacketPlan[] packetPlans = {
        new Measured(20),
        new Tiered("S1", 1000, 10000, 8)
    };
    static final CellPhonePlan[] cellPhonePlans ={
        new CellPhonePlan(callingPlans[0], packetPlans[0]),
        new CellPhonePlan(callingPlans[0], packetPlans[1]),
        new CellPhonePlan(callingPlans[1], packetPlans[0]),
        new CellPhonePlan(callingPlans[1], packetPlans[1])
    };

    static CellPhonePlan getRecommendPlan(int minutes, int packets){
        int minCharge = 問題E;
        CellPhonePlan recomended = null;
        for(CellPhonePlan cellPhonePlan: cellPhonePlans){
            int charge = 問題F;
            if(charge <= minCharge){
                recomended = cellPhonePlan;
                minCharge = charge;
            }
        }
        return recomended;
    }

    以下mainメソッド
}

ここ問題Eを間違えました…(泣)

問題EとFに関して

ア:0
イ:Integer.MIN_VALUE
ウ:Integer.MAX_VALUE
エ:cellPhonePlan.calculateCharge(minutes, packets)
オ:recommended.calculateCharge(minutes, packets)

問題E

minChargeについては、for文内部のif文条件でchargeと比較をしていることがわかります。
charge(費用)がminCharge(低い費用)より小さい時、recommendedとminChargeにもともとのプランやcharge(費用)を退避しています。
各プランをfor文で回しながら費用の比較を行っています。

minChargeのように最小値を検索したい場合、
最小値を格納する変数の初期値に、その変数の型の最大値を代入することが一般的だそうです。
そうすれば絶対に最小値が引っかかりますよね。(確かにって…)

int型の最大値を出したいときはラッパークラスIntegerのMAX_VALUEである、が正解。

問題F

Fは費用を入れる必要があります。
minutes利用時間と、packetsパケット数があるため、これを計算するメソッドcalculateChargeに入れる必要があります。
recommendedをここで入れるのは意味不明なので、拡張for文のcellPhonePlanくんが使っているが正解

感想

ラッパークラスと唐突な初期化に慣れていませんね… でも依然として基礎的な部分が問われていて、 しっかりと変数を読み解いて行ければ良さそうです。