平成29年秋期試験午後問題 問11

午前試験免除制度対応!基本情報技術者試験のeラーニング【独習ゼミ】

問11 ソフトウェア開発(Java)

次のJavaプログラムの説明及びプログラムを読んで,設問1~3に答えよ。
(Javaプログラムで使用するAPIの説明は,こちらを参照してください。)

〔プログラムの説明〕
 文字列の配列を要素にもつ配列で表現された表中の行を,並べ替えるプログラムである。表は行の配列として,行は文字列の配列として構成される。各行の指定した列が,指定した順序に並ぷように,行を並べ替える。
 図1は,表の最左列の文字列を辞書順に,最左列の文字列が等しい行は右隣の列の文字列を数値とみなしたときに降順になるように並べ替えた例である。
pm11_1.png
 クラス TableSorter は,表中の行を並べ替える機能を提供する。次のメソッドと入れ子クラス OrderBy をもつ。
  • putSortOrder(String key,Comparator<String>order) - このクラスのメソッド sort で指定可能な順序を登録する。
    key
    表を並べ替える順序を示すために使用する文字列(以下,順序指定子という)。
    order
    インタフェース Comparator 型のオブジェクトで,key で指定した順序指定子が示す順序を規定する。
  • sort(String[][] table,final OrderBy... orderBys) - 条件として指定した列が指定した順序になるように,表中の行を並べ替える。条件は複数指定できる。並び順の決定には先に指定した条件が優先される。先に指定した条件で並び順が決まらない行については,後に指定した条件を加えて決定する。指定した全ての条件で順序が決まらない行については,並べ替える前の並び順を維持する。
    table
    整列対象の表を格納した String 型の配列を要素にもつ配列を指定する。
    orderBys
    条件を必要なだけ指定する。
 クラス TableSorter の入れ子クラス OrderBy は並べ替えの条件を表すクラスである。フィールド key は順序指定子,フィールド col は比較対象の列の位置を示す数(行を表す String 型配列の添字)である。フィールド isReversed が false であれば,この条件が表す順序が順序指定子 key で指定されるオブジェクトのメソッド compare が返す大小関係での昇順で並べ替えることを意味し,trueであれば,降順で並べ替えることを意味する。

 クラス TableSorterTester はテスト用のプログラムである。
 実行結果を図2に示す。
pm11_2.png
pm11_3.png

設問1

プログラム1中の に入れる正しい答えを,解答群の中から選べ。
a に関する解答群
  • Character,Comparator<String>
  • Character,String
  • String,Comparator<String>
  • String,String
b に関する解答群
  • int i = 0; i < orderBys.length; i++
  • int i = 0; i < table.length; i++
  • OrderBy orderBy : orderBys
  • String[] row : table
c に関する解答群
  • .get(col)
  • .get(orderBy.col)
  • [col]
  • [orderBy.col]
d に関する解答群
  • !=
  • <
  • ==
  • >
e に関する解答群
  • -order
  • order
  • orderBy.isReversed ? -order : order
  • orderBy.isReversed ? order : -order
解答選択欄
  • a:
  • b:
  • c:
  • d:
  • e:
  • a=
  • b=
  • c=
  • d=
  • e=

解説

aについて〕
〔プログラム1〕TableSorter クラスの orderMap は、同クラスの putSortOrder メソッド内で put メソッドを呼び出しています。

Map インタフェースは、Javaプログラムで使用するAPIの説明に
public interface Map
型Kのキーに型 V の値を対応付けて保持するインタフェースを提供する。
各キーは、一つの値としか対応付けられない。
と書かれています。また、putメソッドは
public V put(K key, V value)
(説明省略)
と説明されており、変数宣言時に指定した K と V の型と put メソッドの引数の型は同じになります。

TableSorter クラスの orderMap メソッドは、String 型と Comparetor<String> 型の2つの引数を受け取り、orderMap の put メソッドの第1引数に String 型の変数を、第2引数に Comparator<String> 型の変数を渡しています。よって、この2つと同じ型で orderMap を宣言している事になります。

a=ウ:String, Comparetor<String>

bについて〕
forループ内に
int order = orderMap.get(orderBy.key). …
というコードがあります。sortメソッド内に「orderBy」という変数はまだ現れていません。
また、sort メソッドの引数は「OrderBy... orderBys」と書かれています。これは可変長引数といい、引数の型の後ろにピリオド3つをつけると、そのメソッドに対してその型の引数を複数渡すことができます。変数名もorderBysと複数形です(※複数渡せる実装となっている理由は、問題文中の記述「条件は複数指定できる」ためです)。

解答群の中で orderBy を宣言しているのは「ウ」のみです。

ちなみに、この記述は「拡張for文(for-each文)」と呼びます。従来のfor文と比較して簡潔に記述することができます。

b=ウ:OrderBy orderBy : orderBys

cについて〕
Comparetor インタフェースの compare メソッドに渡す2つの引数にcがあります。変数 s1、s2 は String 型の配列です。消去法となりますが、
  • 引数で渡される s1 と s2 は配列ですので、[]を使った添字でアクセスします。getメソッドはリスト(ArrayList)に定義されているメソッドなので、配列に使うことはできません。
  • 「ア」と同様の理由で誤りです。
  • col という変数は宣言されていません。また、OrderBy クラスの col に直接アクセスはできません。
  • 正しい。[orderBy.col] は、OrderBy クラスの col が s1、s2 配列の添字となります。問題文より、フィールド col は比較対象の列の位置を示す数(行を表すString型配列の添字)です。
c=エ:[orderBy.col]

dについて〕
変数 order には compare メソッドの戻り値が格納されます。
compareメソッドの戻り値は、Javaプログラムで使用するAPIの説明に
o1とo2の大きさが等しいときは0
o1がo2より小さいときは負の値
o1がo2より大きいときは正の値
と書かれています。

この後のeとも関連しますが、このコードは問題文の「フィールド isReserved が false であれば、この条件が表す順序が順序指定子 key で指定されるオブジェクトのメソッド compare が返す大小関係の昇順で並べ替えることを意味し、true であれば、降順で並べ替えることを意味する」に相当する処理です。

compare メソッドの結果を逆にしたいので、compare メソッドの戻り値(=order変数)が0以外のときに特定の処理を実行すれば問題文の説明に合致する処理になります。

d=ア:!=

eについて〕
Arrays.sort メソッドは、Javaプログラムで使用するAPIの説明に「(省略)…昇順に並べ替える」と記載されています。また、問題文中には「フィールド isReserved が false であれば(省略)昇順で並べ替えることを意味し、true であれば、降順で並べ替えることを意味する」とあります。すなわち、isReserved が false の場合はそのままで、true の場合は逆にします。

正解は「ウ」です。

これは、三項演算子と呼ばれる書き方で、
条件式 ? trueの場合の評価式 : falseの場合の評価式
という構文になります。正解の「orderBy.isReserved ? -order : order」を例にすると、isReserved が true の場合は -order を、false の場合は order がそのまま返却されます。
  • 無条件に order を逆にしています。
  • 無条件に order をそのままにしています。
  • 正しい。
  • 問題文の記述と逆の実装です。isReserved が true の場合はそのまま(昇順)、false の場合は逆(降順)になってしまいます。
e=ウ:orderBy.isReserved ? -order : order

設問2

プログラム2のαで示した2行を次の2行と入れ替えて実行したとき,実行結果の1行目に出力される内容として正しい答えを,解答群の中から選べ。
pm11_4.png
解答群
  • apple 2 300
  • apple 3 1,000
  • banana 1 300
  • banana 2 2,000
  • cherry 1 1,000
解答選択欄
  •  
  •  

解説

〔プログラム2〕TableSorterTester クラスの中で、TableSorter クラスのインスタンスを sorter という変数で生成しています。sorter.putSortOrder メソッドが2度現れており、それぞれ第1引数が"lex"と"num"となっています。

"lex"のほうはその後のコードを見ると
return o1.compareTo(o2);
と書かれており、文字列による比較を行っていることがわかります。

一方"num"は
return new Integer(o1).compareTo(new Integer(o2));
と書かれており、数値による比較です。

つまり、αの部分は
TableSorter.OrderBy("lex", 0) //1列目を文字列で昇順にソート
TableSorter.OrderBy("num", 1, true) //2列目を数値順で降順にソート
を意味しています。

OrderBy クラスのコンストラクタは、引数が2つの場合と3つの場合でオーバーロードしています。引数が3つの場合は isReserved に第3引数を設定しており、2つの場合は引数3つのコンストラクタを呼び出しており、第3引数は false 固定です(isReserved が false の場合は昇順、true の場合は降順で並べ替えることを意味しています)。

これを設問2のコードに入れ替えると、
TableSorter.OrderBy("lex", 2) //3列目を文字列で昇順にソート
TableSorter.OrderBy("lex", 0) //1列目を文字列で昇順にソート
となります。

最初は下記のように並んでいます。
pm11_6.png
まず、3列目を文字列で昇順にソートすると、1,000、2,000、300の順でソートされます。文字列比較の場合は数値ではなく文字ごとに大小比較するためです。つまり先頭の1、2、3で比較します。
pm11_7.png
続いて、1列目を文字列で昇順にソートします。appleとcherryを比較した場合、appleのほうが先です。またappleとbananaを比較した場合もappleのほうが先です。よって、最終的な結果は下記となります。
pm11_8.png
したがって、実行結果の1行目に出力されるのは「apple 3 1,000」です。

∴イ:apple 3 1,000

設問3

プログラム2のαで示した2行を次の8行と入れ替えて実行したとき,実行結果の3行目に出力される内容として正しい答えを,解答群の中から選べ。
pm11_5.png
解答群
  • apple 2 300
  • apple 3 1,000
  • banana 1 300
  • banana 2 2,000
  • cherry 1 1,000
解答選択欄
  •  
  •  

解説

既存の"lex"、"num"に、"numC"という定義が増えています。"numC"のコードを確認すると、
return new Integer(s1.replace(",", ""))
 .compareTo(new Integer(s2.replace(",", "")));
と書かれており、文字列中のカンマを取り除いて数値として比較しています。

設問3のソート条件は
TableSorter.OrderBy("numC", 2) //3列目をカンマを取り除いた数値で昇順にソート
TableSorter.OrderBy("lex", 0) //1列目を文字列で昇順にソート
となります。

最初は下記のように並んでいます。
pm11_6.png
まず、3列目をカンマを取り除いた数値で昇順にソートすると、300、1000、2000の順でソートされます。
pm11_9.png
続いて、1列目を文字列で昇順にソートします。1行目と2行目の1列目、bananaとappleを比較した場合、appleのほうが先です。同様に、3行目と4行目の1列目、appleとcherryを比較した場合、appleのほうが先です。よって、最終的な結果は下記となります。
pm11_10.png
したがって、実行結果の3行目に出力されるのは「apple 3 1,000」です。

∴イ:apple 3 1,000

Pagetop