基本情報技術者 2019年 春期 午後 問10
次のCOBOLプログラムの説明及びプログラムを読んで、設問1,2に答えよ。
〔プログラムの説明〕
地域の5か所に建物(以下、校舎という)をもち、中学生向けの進学指導を行っているP学習塾では、定期的にテストを実施している。全ての塾生は、国語、数学、英語、理科及び社会の5教科のテストを受ける。テスト結果は、1回分を学年別の結果ファイルに格納する。各校舎の各学年には1名以上の塾生が所属しており、1学年の人数は塾全体で999人を超えることはない。
このプログラムは、結果ファイルに格納されたある学年のテスト結果を塾生ごとに集計して、5教科の得点の合計(以下、合計点という)の降順に並べた順位リストを印字する。
(1) 結果ファイルは、図1に示すレコード様式の順ファイルであり、1学年分のレコードが格納されている。

① 塾生番号は、塾全体で一意となる番号である。
② 校舎番号には、塾生番号で示される塾生が所属する校舎の番号が01〜05で格納されている。
③ テスト結果には、塾生番号で示される塾生の各教科の得点が000〜100で格納されている。
(2) 順位リストは、図2に示す印字様式である。見出しは印刷済みとする。

① 全体順位には塾全体での順位を、校舎内順位には塾生が所属する校舎での順位を印字する。印字行は合計点の降順に並べる。
② 同じ合計点の塾生は同じ順位とする。例えば、塾全体で合計点の高い塾生から、492点が1名、488点が2名、487点が1名いた場合は、図3のように順位付けして印字する。


設問1:
問題文を見る プログラム中のに入れる正しい答えを、解答群の中から選べ。
aに関する解答群
ア:ASCENDING KEY SRT-NO
イ:ASCENDING KEY SRT-TOTAL
ウ:DESCENDING KEY SRT-NO
エ:DESCENDING KEY SRT-TOTAL
bに関する解答群
ア:ADD 1 TO ALL-ORD-NO BLD-ORD-NO(SRT-BLD)
イ:ADD 1 TO ALL-RANK BLD-RANK(SRT-BLD)
ウ:INITIALIZE BLD-INF
エ:MOVE ALL-ORD-NO TO BLD-ORD-NO(SRT-BLD)
c, dに関する解答群
ア:MOVE ALL-CR-TOTAL TO ALL-RANK
イ:MOVE ALL-ORD-NO TO ALL-RANK
ウ:MOVE ALL-ORD-NO TO BLD-RANK(SRT-BLD)
エ:MOVE BLD-CR-TOTAL(SRT-BLD) TO BLD-RANK(SRT-BLD)
オ:MOVE BLD-ORD-NO(SRT-BLD) TO ALL-RANK
カ:MOVE BLD-ORD-NO(SRT-BLD) TO BLD-RANK(SRT-BLD)
模範解答
a:エ、b:ア、c:イ、d:カ
解説
解答の導き方
このプログラムは、塾生ごとの合計点を計算し、合計点の高い順に並べてから、全体順位と校舎内順位を印字します。COBOL(Common Business-Oriented Language:事務処理向けのプログラミング言語)のSORTは、指定した項目を基準にデータを並べ替える機能です。
1. 合計点の高い順に並べます
入力した各塾生の結果から、国語、数学、英語、理科及び社会の得点を足し、SRT-TOTALに格納しています。各教科の得点は最大100点なので、合計点は最大でも 点です。
順位リストは合計点の降順、つまり高い点から低い点へ並べる必要があります。そのため、SORTで指定する項目はSRT-TOTALで、並べる向きは降順です。よって、aには「DESCENDING KEY SRT-TOTAL」が入ります。これは解答群のエです。
2. それぞれの塾生が何番目に現れたかを数えます
SORT後のレコードを処理するたびに、PRT-PROCが実行されます。ここでは、順位を決める前に、全体と該当する校舎の通し位置を数える必要があります。
ALL-ORD-NOは、SORT後に処理した塾生の人数を全体で数えます。BLD-ORD-NO(SRT-BLD)は、塾生が所属する校舎ごとに人数を数えます。どちらも最初は0なので、1人処理するごとに1を加えます。
したがって、bには「ADD 1 TO ALL-ORD-NO BLD-ORD-NO(SRT-BLD)」が入ります。これは解答群のアです。
ここで数えているのは、同じ点の塾生を同じ順位にするための順位そのものではなく、処理した人数です。順位は、この通し位置を使って後から決めます。
3. 点数が下がったときに順位を更新します
ALL-CR-TOTALには、直前までに処理した合計点が入ります。SRT-TOTALがALL-CR-TOTALより小さいとき、つまり点数が前の塾生より下がったときに、全体順位を更新します。
更新する順位は、その合計点の塾生が現れた位置です。よって、cには「MOVE ALL-ORD-NO TO ALL-RANK」が入ります。これは解答群のイです。
校舎内順位も同じ考え方です。ただし、比べるのはその校舎で直前までに処理した合計点です。点数が下がったとき、その校舎の通し位置を校舎内順位に設定します。よって、dには「MOVE BLD-ORD-NO(SRT-BLD) TO BLD-RANK(SRT-BLD)」が入ります。これは解答群のカです。
4. 同じ合計点の順位が同じになることを確認します
条件が「SRT-TOTAL < ALL-CR-TOTAL」のように「より小さい」ときだけ順位を更新する点が重要です。同じ合計点なら条件が成立しないため、直前の順位がそのまま使われます。
図3のように、合計点が492点の塾生が1人、488点の塾生が2人、487点の塾生が1人の場合を考えます。
488点の2人目は通し位置が3になりますが、合計点が直前の塾生と同じなので順位は更新されません。その後、487点になったところで通し位置の4が順位になります。このため、同じ点の塾生には同じ順位が付き、次の点数の順位には同じ点の人数が反映されます。
校舎内順位も、校舎ごとの通し位置と直前の合計点を使って同様に決まります。図3では、合計点が488点の塾生はどちらも全体順位が2ですが、所属する校舎でそれまでに処理した人数が異なるため、校舎内順位は異なっています。
誤りやすいポイント
- 合計点の降順は、「点数の小さい順」ではありません。高い点から並べるので、SRT-TOTALを降順のキーにします。
- ALL-ORD-NOやBLD-ORD-NOは通し位置を数える項目です。毎回加算しますが、ALL-RANKやBLD-RANKは点数が下がったときだけ更新します。
- 同点の場合は順位を更新しません。「より小さい」という条件なので、同点の塾生は同じ順位になります。
- 校舎内順位を決めるときは、全体の通し位置ではなく、該当する校舎のBLD-ORD-NO(SRT-BLD)を使います。
FAQ
Q: 同じ合計点の塾生が続くとき、なぜ順位を毎回更新しないのですか?
A: 条件が「現在の合計点が直前の合計点より小さいとき」だけ成立するからです。同じ点数では順位が変わらず、同じ順位になります。
A: 条件が「現在の合計点が直前の合計点より小さいとき」だけ成立するからです。同じ点数では順位が変わらず、同じ順位になります。
Q: 点数が487点になったとき、なぜ順位が3ではなく4になるのですか?
A: その前に492点の塾生が1人、488点の塾生が2人いるため、487点の塾生は全体で4番目に処理されます。通し位置の4が順位になります。
A: その前に492点の塾生が1人、488点の塾生が2人いるため、487点の塾生は全体で4番目に処理されます。通し位置の4が順位になります。
Q: ALL-CR-TOTALとBLD-CR-TOTALの初期値が999なのはなぜですか?
A: 合計点は最大500点なので、最初の塾生の点数は999より小さくなります。そのため、最初の塾生を処理するときにも順位を更新できます。
A: 合計点は最大500点なので、最初の塾生の点数は999より小さくなります。そのため、最初の塾生を処理するときにも順位を更新できます。
関連キーワード: ソート、ソートキー、順ファイル、配列、順位付け
設問2:
問題文を見る 図4の表示様式に示すとおり、“AVG:”に続けて塾全体の平均点を表示し、“BLD-AVG:”に続けて校舎ごとの平均点を、校舎番号01〜05の昇順に表示するようにプログラムを変更する。表1中のに入れる正しい答えを、解答群の中から選べ。


eに関する解答群
ア:行番号50と51の間
イ:行番号51と52の間
ウ:行番号62と63の間
エ:行番号79の後ろ
fに関する解答群
ア:BLD-TOTAL(CNT) / BLD-ORD-NO(CNT)
イ:BLD-TOTAL(CNT) / BLD-ORD-NO(SRT-BLD)
ウ:BLD-TOTAL(CNT) / BLD-RANK(CNT)
エ:BLD-TOTAL(CNT) / BLD-RANK(SRT-BLD)
模範解答
e:エ、f:ア
解説
解答の導き方
この設問では、全体と校舎ごとの合計点をためておき、それぞれの平均点を表示するために、処理をどこに追加するかを考えます。
COBOL(Common Business-Oriented Language:事務処理向けのプログラミング言語)では、SORTでレコードを並べ替え、RETURNで並べ替え後のレコードを1件ずつ取り出します。このプログラムは、取り出したレコードを使って順位リストを印字するため、印字処理の中では塾生1人分の校舎番号と合計点を参照できます。
平均点は、合計点の総和を人数で割って求めます。つまり、次の2種類の合計と人数が必要です。
- 塾全体の平均点:全塾生の合計点の総和 ÷ 全塾生の人数
- 校舎ごとの平均点:その校舎の塾生の合計点の総和 ÷ その校舎の塾生の人数
表1で追加するALL-TOTALは塾全体の合計点の総和、BLD-TOTALは校舎ごとの合計点の総和を記録します。BLD-TOTALはOCCURS 5で5個用意されており、校舎ごとに別々の合計を記録できます。
人数には、順位処理で使うALL-ORD-NOとBLD-ORD-NOを利用できます。ALL-ORD-NOは全塾生の人数、BLD-ORD-NOの各要素は各校舎の塾生の人数に対応します。
eを考えます。 合計点の総和は、塾生1人分の合計点を、処理するたびに加えていく必要があります。順位リストを印字するPRT-PROCは、RETURNでレコードを1件受け取るたびに呼び出されます。そのため、現在のレコードの合計点SRT-TOTALと校舎番号SRT-BLDを使い、全体の合計と該当する校舎の合計を更新できます。
表1の追加処理である「ADD SRT-TOTAL TO ALL-TOTAL BLD-TOTAL(SRT-BLD).」は、現在の合計点をALL-TOTALと、該当する校舎のBLD-TOTALに加えます。これを塾生ごとに1回ずつ実行するには、PRT-PROCの中に置く必要があります。行番号79のWRITE PRT-REC.の後ろなら、PRT-PROCが呼び出されるたびに実行されます。この位置がeに当てはまります。
ほかの位置では、必要な回数やタイミングになりません。
- 行番号50と51の間は、結果ファイルの読み込みが終わった後に実行される位置です。塾生ごとの合計点を順に加える処理にはなりません。
- 行番号51と52の間は、CALC-PROCの処理が始まった直後です。現在のレコードの合計点SRT-TOTALを計算する前なので、そのレコードの合計点を加える位置として適切ではありません。
- 行番号62と63の間は、並べ替え後のレコードをすべて処理し終わった後です。塾生ごとに加算する処理にはなりません。
- 行番号79の後ろは、PRT-PROC内で塾生ごとに実行されるため、合計点を1人分ずつ加算できます。
fを考えます。 表1では、校舎ごとの平均点をCNTの値を使って順番に求めます。CNTは1から5まで変化するため、CNTを配列の添字に使えば、校舎ごとの値を校舎番号01〜05の順に取り出せます。
したがって、各回で使うのは、その校舎の合計点の総和と、その校舎の人数です。式は次のとおりです。
プログラムでは、合計点の総和がBLD-TOTAL(CNT)、人数がBLD-ORD-NO(CNT)なので、BLD-AVG(CNT)にはBLD-TOTAL(CNT) / BLD-ORD-NO(CNT)を計算します。これがfに当てはまります。
BLD-RANK(CNT)は校舎内順位を表す値であり、人数ではありません。また、SRT-BLDは現在処理している塾生の校舎番号です。表示処理ではCNTで校舎を順番に選んでいるため、ここで使う添字もCNTにそろえる必要があります。
誤りやすいポイント
- 合計点を加算する処理を、結果ファイルの読み込み後に1回だけ実行してしまうことです。合計点の総和は、塾生1人分ずつ加算する必要があります。
- 平均点の分母に順位を使ってしまうことです。順位は成績の順番を表すもので、人数とは異なります。
- 校舎ごとの平均点なのに、全塾生の人数ALL-ORD-NOで割ってしまうことです。校舎ごとの人数であるBLD-ORD-NOを使います。
- 校舎ごとの平均点を表示するループで、CNTではなくSRT-BLDを使ってしまうことです。CNTは表示対象の校舎を順番に選ぶための値です。
FAQ
Q: 合計点を加算するのは、印字の前でなければいけませんか。
A: この設問では、印字の後に加算しても問題ありません。PRT-PROCが塾生ごとに1回実行され、平均点を表示する処理は全レコードの処理後に行われるためです。
A: この設問では、印字の後に加算しても問題ありません。PRT-PROCが塾生ごとに1回実行され、平均点を表示する処理は全レコードの処理後に行われるためです。
Q: BLD-RANK(CNT)を平均点の分母に使えないのはなぜですか。
A: BLD-RANK(CNT)は校舎内順位です。人数ではないので、合計点の総和を割る相手にはなりません。
A: BLD-RANK(CNT)は校舎内順位です。人数ではないので、合計点の総和を割る相手にはなりません。
Q: BLD-TOTAL(CNT)とBLD-ORD-NO(CNT)で、同じCNTを使うのはなぜですか。
A: CNTが示す同じ校舎について、合計点の総和と人数を取り出すためです。添字をそろえることで、別の校舎の合計と人数を組み合わせる誤りを防げます。
A: CNTが示す同じ校舎について、合計点の総和と人数を取り出すためです。添字をそろえることで、別の校舎の合計と人数を組み合わせる誤りを防げます。
関連キーワード: 平均値、配列、累積処理、順位付け、ソート



