基本情報技術者 2015年 秋期 午後 問10
次のCOBOLプログラムの説明及びプログラムを読んで、設問1,2に答えよ。
〔プログラムの説明〕
D社では、ある製品の満足度を調べるために、アンケート調査を実施し、得られた1,000件の回答をアンケート結果ファイルに登録した。このプログラムは、アンケート結果ファイルを読み込み、集計結果をグラフで表示する。
(1) アンケート結果ファイルは、図1に示すレコード様式の順ファイルである。


① 回答IDは、一意に割り振られた0001〜1000の番号である。
② 価格満足度、機能満足度及びデザイン満足度は、それぞれの満足度の高から低を5〜1の5段階で評価したものである。
(2) 集計した満足度の分布をヒストグラムで表示する。図2に集計結果の表示例を示す。
① 価格(Price)、機能(Function)及びデザイン(Design)の各項目のヒストグラムを並べて表示する。
② 各ヒストグラムは、項目名の行と満足度5〜1の行の6行から成る。
③ 各満足度の行は、満足度の値、その満足度の選択数、選択数を長さで表す横棒の順に表示する。
④ 選択数は、値が0の場合以外は先行する数字0を除いて、値が0の場合は1桁の数字0を、右寄せで表示する。
⑤ 横棒は、選択数20ごとに記号“*”を一つ用いて表示する。選択数が20に満たない端数は切り捨てる。


設問1:
問題文を見る プログラム中のに入れる正しい答えを、解答群の中から選べ。
aに関する解答群
ア:9(4)
イ:B(3)9
ウ:Z(3)9
エ:Z(4)
bに関する解答群
ア:CNT-NUM(6 - I, J)
イ:CNT-NUM(I, 5 - J)
ウ:CNT-NUM(I, 6 - J)
エ:CNT-NUM(I, J)
cに関する解答群
ア:1:PLOT-NUM
イ:1:PLOT-NUM + 1
ウ:PLOT-NUM
エ:PLOT-NUM + 1
dに関する解答群
ア:HIST-NUM
イ:HIST-PLOT
ウ:HIST-REC
エ:HIST-VAL
模範解答
a:ウ、b:エ、c:ア、d:ウ
解説
解答の導き方
このプログラムは、アンケート結果ファイルを読み、価格・機能・デザインそれぞれについて、満足度ごとの回答数と横棒を表示します。COBOL(Common Business-Oriented Language:事務処理向けのプログラミング言語)のプログラムを、集計する部分、表示する部分の順に追いながら、空欄を考えます。
まず、回答を集計する部分を確認します。CNT-SATISは3項目、CNT-VALは満足度の値ごとに5個の領域を持ちます。したがって、CNT-NUM(I, J)は、項目Iにおける満足度Jの回答数を表します。
プログラムは、回答の満足度をANS-VAL(I)からJに入れ、その値に対応するCNT-NUM(I, J)を1増やします。満足度は5〜1の値なので、満足度の値をそのまま2番目の添字Jに使えます。たとえば、価格の満足度が4なら、価格の満足度4に対応する回答数が増えます。
表示する部分では、Jを5から1まで減らしながら、満足度の高い順に各行を作ります。表示する回答数は、その項目Iと満足度Jに対応する集計値です。そのため、bにはCNT-NUM(I, J)が入ります。
次に、aは回答数を表示する領域HIST-NUMの形式です。問題文には、選択数は0以外なら先頭の0を除き、0なら1桁の0を表示するとあります。回答数は最大1,000件なので、4桁分の領域が必要です。
PIC 9(4)は4桁を表示できますが、69のような数も先頭に0を付けて表示します。一方、PIC Z(3)9では、先頭側のZが不要な0を空白にし、最後の9は数字として表示します。そのため、69は右寄せで表示され、0も最後の桁に表示されます。よって、aはZ(3)9です。
横棒の長さは、選択数20ごとに記号*を1つ表示することで決まります。そこで、選択数を20で割り、整数部分をPLOT-NUMに入れます。たとえば、選択数が69なら、69÷20は3余り9なので、星は3個です。余りは切り捨てます。
HIST-PLOTは50文字分の領域です。COBOLでは、文字列の一部分を指定するとき、開始位置と文字数を指定できます。開始位置を1、文字数をPLOT-NUMにすれば、先頭から必要な数だけ*を入れられます。したがって、cは1:PLOT-NUMです。処理の前にHIST-PLOT全体を空白にしているので、指定した部分以外は空白のままです。
最後に、HIST-RECには、満足度の値、空白、回答数、空白、横棒が順に含まれています。1行分の表示をまとめて行うには、これらの項目を含むグループ全体をDISPLAYに指定します。したがって、dはHIST-RECです。DISPLAYは、指定したデータを画面に表示する命令です。
誤りやすいポイント
- CNT-NUM(I, J)のJを、満足度の値とは別の順番に変換してしまうことがあります。このプログラムでは満足度が1〜5なので、その値をそのまま添字に使います。
- PIC 9(4)は4桁分の領域ですが、先頭の0を表示します。右寄せで先頭の0を省くには、Zを使います。
- PIC Z(4)では、0の場合に最後の桁も0として表示する指定がありません。0を1桁で表示するため、最後の桁には9が必要です。
- 横棒の文字数に、選択数を20で割った余りまで加えないようにします。指定では、20に満たない端数は切り捨てます。
- HIST-PLOT全体に*を入れるのではなく、必要な文字数だけを指定します。選択数が20未満ならPLOT-NUMは0となり、横棒は表示されません。
FAQ
Q: なぜ満足度の表示は5から始まるのですか?
A: プログラムの表示ループがJを5から1まで減らすためです。問題文の表示例と同じく、満足度の高い順に並びます。
A: プログラムの表示ループがJを5から1まで減らすためです。問題文の表示例と同じく、満足度の高い順に並びます。
Q: 選択数が69の場合、横棒は何個になりますか?
A: 69を20で割った整数部分は3です。余りの9は切り捨てるので、横棒は3個です。
A: 69を20で割った整数部分は3です。余りの9は切り捨てるので、横棒は3個です。
Q: HIST-VALやHIST-NUMだけでなく、HIST-RECを表示するのはなぜですか?
A: HIST-RECには、満足度、回答数、横棒と、それらの間の空白がまとめて入っています。HIST-RECを表示すれば、1行分をまとめて出力できます。
A: HIST-RECには、満足度、回答数、横棒と、それらの間の空白がまとめて入っています。HIST-RECを表示すれば、1行分をまとめて出力できます。
関連キーワード: 順ファイル、配列、集計処理、数字編集項目、文字列の部分指定、ヒストグラム
設問2:
問題文を見る 各回答の3項目の満足度を加算した値(以下、総合満足度という)を求め、総合満足度ごとの回答IDの一覧を追加して表示するよう、プログラムを変更する。追加した部分の表示例を図3に示す。表1中のに入れる正しい答えを、解答群の中から選べ。
① 総合満足度の昇順に、その値と該当する全ての回答IDを表示する。
② 回答IDは、総合満足度ごとに昇順に表示する。
③ 回答IDは、10件ごとに改行して表示する。
④ 回答が1件もない総合満足度の値に対しては、表示を省略する。


eに関する解答群
ア:SRT-ID
イ:SRT-REC
ウ:SRT-SUM
f, gに関する解答群
ア:POS > 1
イ:POS > 10
ウ:SRT-SUM NOT = LAST-SUM
エ:SRT-SUM NOT = LAST-SUM AND POS > 1
オ:SRT-SUM NOT = LAST-SUM AND POS > 10
カ:SRT-SUM NOT = LAST-SUM OR POS > 1
キ:SRT-SUM NOT = LAST-SUM OR POS > 10
模範解答
e:イ、f:キ、g:ウ
解説
解答の導き方
この変更では、各回答の満足度を合計し、合計値ごとに回答IDを並べます。さらに、同じ合計値の回答IDが多い場合は、10件ずつ表示します。
-
ソートするデータの並びを確認します。
COBOL(Common Business-Oriented Language:事務処理向けのプログラミング言語)で扱うレコードは、1回答分のデータをまとめたものです。追加するレコード「SRT-REC」には、先に総合満足度の「SRT-SUM」、次に回答IDの「SRT-ID」が入ります。総合満足度は3項目の満足度を足した値です。各項目は1〜5なので、合計値の最小は 、最大は です。ソートとは、データを決められた順番に並べ替える処理です。総合満足度を昇順にし、同じ総合満足度の中では回答IDも昇順にする必要があります。「SRT-REC」全体をソートの基準にすると、先頭の「SRT-SUM」の順に並び、総合満足度が同じレコードの中では、続く「SRT-ID」の順に並びます。したがって、eには「SRT-REC」が入ります。 -
一覧を表示する区切りを考えます。
「T-SATIS-IDS OCCURS 10」は、回答IDを10件分入れる欄です。「POS」は次に回答IDを入れる位置として使われます。1から始まる「POS」は、回答IDを入れるたびに1増えるため、10件を入れ終わると11になります。表示中の総合満足度が変わった場合は、前の総合満足度の回答IDを表示して、新しい値の一覧に切り替えます。また、総合満足度が同じままでも、10件を入れ終わったら、その10件を表示して次の欄に移ります。つまり、区切る条件は「総合満足度が変わった」または「10件を入れ終わった」です。よってfには「SRT-SUM NOT = LAST-SUM OR POS > 10」が入ります。「IF POS > 1」は、表示する回答IDが欄にすでに入っているかを確認しています。最初のレコードでは「POS」が1なので、まだ空の欄を表示しません。 -
総合満足度を書き込むタイミングを考えます。
「LAST-SUM」は、現在処理している総合満足度を記録します。総合満足度が変わったときだけ、「SRT-SUM」を「T-SATIS-SUM」と「LAST-SUM」に移します。そのため、gには「SRT-SUM NOT = LAST-SUM」が入ります。「POS > 10」だけが理由で区切る場合は、同じ総合満足度の回答IDを続けて表示している途中です。新しい総合満足度に切り替わったわけではないため、「LAST-SUM」を更新する必要はありません。 -
最後に残った回答IDも表示します。
一覧の途中では、総合満足度が変わったときや、10件を入れ終わったときに、それまでの一覧を表示します。一方、最後の一覧には次のレコードがありません。そのため、ループを抜けた後の「DISPLAY T-SATIS-REC」で残りを表示します。
誤りやすいポイント
- 「SRT-SUM」だけをキーにすると、総合満足度の順には並びますが、同じ総合満足度の中で回答IDを昇順にする条件を満たせません。レコードの並びが「総合満足度、回答ID」の順になっている点が重要です。
- 「POS > 10」は、11件目を入れる前に判定されます。10件を入れた直後に「POS」が11になるため、条件を満たしたら、10件を表示してから次の回答IDを入れます。
- 総合満足度の変化だけを区切り条件にすると、同じ総合満足度の回答IDが10件を超えたときに、10件ずつ表示できません。
- 10件を入れ終わった場合だけを区切り条件にすると、10件未満で総合満足度が変わったときに、異なる総合満足度の回答IDが同じ欄に混ざってしまいます。
- 総合満足度が変わったときと、10件を入れ終わったときは、どちらも区切る理由になります。そのため、条件はANDではなくORです。
FAQ
Q: どうして回答IDの一覧を10件ずつに分けるのですか?
A: 「T-SATIS-IDS OCCURS 10」に回答IDを入れる欄が10件分しかないためです。10件を入れ終えたら表示し、次の欄に移ります。
A: 「T-SATIS-IDS OCCURS 10」に回答IDを入れる欄が10件分しかないためです。10件を入れ終えたら表示し、次の欄に移ります。
Q: 回答がない総合満足度の値は、どこで表示しないようにしていますか?
A: ソート後のレコードを順に処理し、実際に現れた総合満足度が変わったときだけ新しい値を書き込みます。回答レコードがない値は処理されないため、表示されません。
A: ソート後のレコードを順に処理し、実際に現れた総合満足度が変わったときだけ新しい値を書き込みます。回答レコードがない値は処理されないため、表示されません。
Q: 最後の一覧を、ループの中で表示できないのですか?
A: ループの中では、次のレコードを確認して区切りを判断します。最後のレコードの後には次のレコードがないため、ループを抜けた後に残っている一覧を表示します。
A: ループの中では、次のレコードを確認して区切りを判断します。最後のレコードの後には次のレコードがないため、ループを抜けた後に残っている一覧を表示します。
関連キーワード: ソート、ソートキー、順ファイル、集計、配列、COBOL



