戦国IT - 情報処理技術者試験の過去問対策サイト
ブログお知らせお問い合わせ料金プラン

基本情報技術者 2016年 春期 午後 問10


次のCOBOLプログラムの説明及びプログラムを読んで、設問1,2に答えよ。

〔プログラムの説明〕  Z社では、従業員向けの福利厚生施設として、6部屋の客室を有する保養所を運営している。1部屋には4人まで宿泊可能で、宿泊希望者は1〜6までの部屋数を指定できる。宿泊日数は1泊だけである。このプログラムは宿泊予約を管理するサブプログラムであり、予約情報を受け取り、予約結果を呼出し元へ返す。 (1) このプログラムのパラメタは二つで、各パラメタの様式は、図1のとおりである。
基本情報技術者試験(平成28年 午後 問10 図1)
 ① 予約番号には、予約希望に対して一意に割り振られた000001〜999999の番号が格納されている。  ② 希望日には、宿泊する日の年、月、日が、それぞれ西暦の4桁、2桁、2桁で格納されている。  ③ 部屋数には、希望する部屋数が格納されている。  ④ 結果には、希望どおりに予約できた場合は0を、できなかった場合は9を設定する。  ⑤ 空き部屋数には、希望どおりに予約できなかった場合に、希望日の空き部屋数を設定する。例えば、3部屋を希望している場合に2部屋しか空きがなかったときは、2を設定する。希望どおりに予約できた場合は、0を設定する。  ⑥ 予約情報に誤りはないものとする。
(2) 予約ファイルは、日付を主キーとする図2に示すレコード様式の索引ファイルであり、予約状況を管理する。
基本情報技術者試験(平成28年 午後 問10 図2)
 ① 日付には、年、月、日が、それぞれ西暦の4桁、2桁、2桁で格納されている。  ② 部屋1〜6のうち、予約済みの部屋には予約番号が格納される。予約が入っていない部屋には0が格納されている。  ③ 予約が1部屋も入っていない日のレコードは存在しない。
基本情報技術者試験(平成28年 午後 問10 プログラム)

設問1:

問題文を見る
 プログラム中のに入れる正しい答えを、解答群の中から選べ。   aに関する解答群  ア:ADD 1 TO GET-ROOM  イ:ADD 1 TO PRM-FREE  ウ:MOVE PRM-NO TO RSV-NO(CNT)  エ:MOVE ZERO TO RSV-NO(CNT)   b, cに関する解答群  ア:CNT > 6  イ:CNT > GET-ROOM  ウ:CNT > PRM-ROOM  エ:GET-ROOM < PRM-ROOM  オ:GET-ROOM = PRM-ROOM  カ:GET-ROOM > PRM-ROOM

模範解答

a:ウ、b:ア、c:オ

解説

解答の導き方

このプログラムは、希望日に予約できる部屋があるかを調べ、予約できる場合は予約ファイルを更新します。予約ファイルは、日付を主キー(レコードを1件に特定する項目)とする索引ファイル(キーを使って目的のレコードを探せるファイル)です。
まず、指定日のレコードが見つからない場合と、すでにレコードがある場合に分けて考えます。23行目のREADは、指定日のレコードを読み込みます。レコードが見つからないときはRSV-PROC、見つかったときはCHK-PROCを実行します。
a:指定日のレコードがない場合
RSV-PROCでは、29行目のINITIALIZE RSV-RECによってレコードの内容を初期化します。部屋1〜6の予約番号は0になり、30行目で希望日が設定されます。
その後、CNTを1から始め、希望する部屋数まで繰り返します。新しいレコードでは部屋がすべて空いているため、希望する部屋の欄に予約番号を設定すれば予約できます。したがって、32行目には予約番号PRM-NOを部屋CNTの欄RSV-NO(CNT)に移す処理が入ります。
b:指定日のレコードがある場合
CHK-PROCでは、GET-ROOMを0にしてから、各部屋の状態を確認します。GET-ROOMは、この予約で確保した部屋数です。PRM-FREEは、希望日に空いている部屋数を数えます。
予約状況は部屋1〜6それぞれに記録されています。希望する部屋数だけを調べるのではなく、空き部屋を探すため、部屋をすべて確認する必要があります。
PERFORM VARYINGは、CNTを1ずつ増やしながら、UNTILの条件が成立するまで処理を繰り返します。部屋が6室あるので、CNTが7になったときに終了する条件、つまり「CNT > 6」が入ります。
部屋が空いているときは、39行目の条件により処理します。まだ希望数を確保できていなければ、予約番号を書き込み、GET-ROOMを1増やします。また、その部屋が空いていたことを数えるため、PRM-FREEも1増やします。
c:希望数を確保できたかの判定
6室すべてを調べた後、GET-ROOMには実際に確保できた部屋数が入っています。希望数と確保数が等しければ、希望どおりに予約できたことになります。したがって、47行目の条件は「GET-ROOM = PRM-ROOM」です。
この条件が成立した場合はRSV-RECを書き換え、結果を0にします。また、仕様では希望どおりに予約できた場合の空き部屋数も0にするため、PRM-FREEも0にします。
条件が成立しない場合は、確保できた部屋数が希望数より少ないということです。PRM-RSLTには9が設定され、PRM-FREEには、確認した空き部屋数が返されます。この場合はREWRITEを実行しないため、予約ファイルには予約内容が保存されません。希望した部屋数に満たないのに、一部の部屋だけ予約されてしまうことを防いでいます。

誤りやすいポイント

  • aでは、空き部屋に0を設定するのではありません。予約が入っていない部屋は初期化で0になっているため、希望する部屋に予約番号を設定します。
  • bのループは、希望する部屋数分だけではなく、6室すべてを調べます。予約済みの部屋が途中にある場合も、ほかの空き部屋を探す必要があるからです。
  • PRM-FREEは「実際に予約できた部屋数」ではありません。希望日に空いていた部屋の数です。予約できた部屋数はGET-ROOMで数えます。
  • 希望数を確保できなかったとき、RSV-RECの一部に予約番号を書いていても、REWRITEを実行しないので予約ファイルは更新されません。

FAQ

Q: GET-ROOMとPRM-FREEは、どちらも部屋数を数えています。何が違いますか?
A: GET-ROOMは、この予約で確保できた部屋数です。PRM-FREEは、希望日の空き部屋数です。希望数を満たせない場合に、空き部屋が何室あったかを返すため、別々に数えています。
Q: 空き部屋が希望数より少ない場合でも、見つかった部屋だけ予約しないのはなぜですか?
A: このプログラムは「希望どおりに予約できた場合」に予約を成立させます。一部だけ予約すると希望と異なる結果になるため、希望数を確保できなければ予約ファイルを更新しません。
Q: 指定日のレコードがない場合は、空き部屋数を調べなくてもよいのですか?
A: 問題文では、予約が1部屋も入っていない日のレコードは存在しないとされています。そのため、指定日のレコードが見つからない場合は、その日に予約が入っていないと判断でき、希望する部屋数を新しいレコードに設定できます。

関連キーワード: COBOL、索引ファイル、主キー、レコード、ループ、条件分岐

解説を読んでも分からないところは、AIに質問できます。 この問題の本文と解説をふまえて答えます。

この設問をAIに質問する

クイズモードで開きます(AIへの質問は無料の会員登録で使えます)

 予約をキャンセルする場合は、宿泊する日の7日前からキャンセル料が発生する。希望どおり予約できた場合には、キャンセル料の発生開始日もパラメタで返すように、プログラムを変更する。キャンセル料の発生開始日の年、月、日は、それぞれ西暦の4桁、2桁、2桁で表し、予約できなかった場合には0を設定する。キャンセル料の発生開始日を求める処理は2016年〜2099年で動作を保証する。表中のに入れる正しい答えを、解答群の中から選べ。
基本情報技術者試験(平成28年 午後 問10 表1)
dに関する解答群  ア:行番号25と26の間  イ:行番号35と36の間  ウ:行番号37と38の間  エ:行番号46と47の間   eに関する解答群  ア:COMPUTE CAN-DD = 30 + CAN-DD - 7  イ:COMPUTE CAN-DD = MONTH-ELM(CAN-MM - 1) - 7  ウ:COMPUTE CAN-DD = MONTH-ELM(CAN-MM) + CAN-DD - 7  エ:SUBTRACT 7 FROM CAN-DD   fに関する解答群  ア:QUOTIENT > 100  イ:QUOTIENT > 400  ウ:URU-SUPPLY = ZERO  エ:URU-SUPPLY NOT = ZERO

模範解答

d:ア、e:ウ、f:ウ

解説

解答の導き方

この設問では、予約できた場合に宿泊日の7日前を求め、予約できなかった場合にはキャンセル料の発生開始日を0にする処理を追加します。追加位置と、日付を7日戻す計算を順に考えます。
d:処理を追加する位置
プログラムでは、READによって予約ファイルを読み込んだ後、該当する日付のレコードがなければRSV-PROCを、あればCHK-PROCを実行します。どちらの処理でも、予約できた場合はPRM-RSLTが0になり、予約できなかった場合は9になります。
追加する処理は、PRM-RSLTが0ならキャンセル料の発生開始日を設定し、そうでなければPRM-CANCELを0にするものです。そのため、RSV-PROCとCHK-PROCのどちらを実行した場合でも、予約結果が決まった後に行う必要があります。
行番号25のEND-READの後なら、どちらの処理の結果も確認できます。また、行番号26のCLOSEより前なので、行番号25と26の間に追加します。したがって、dはアです。
e:月をまたぐ場合の日数計算
宿泊日が月の8日以降なら、CAN-DDから7を引くだけで7日前になります。宿泊日が7日以前なら、前の月に移る必要があります。
1月の場合は、前の月が前年の12月なので、年を1減らし、月を12にします。12月の日数は31日なので、日付は31日と元の日付を使って計算できます。
1月以外の場合は、先にCAN-MMを1減らします。これでCAN-MMは「前の月」を示すため、MONTH-ELM(CAN-MM)から前の月の日数を取り出せます。そこに元の日付を足し、7を引くことで、前の月にさかのぼった日付が求まります。
たとえば、宿泊日が2024年3月5日の場合、月を1減らすと2月になります。2月の日数は通常28日なので、日です。うるう年なら、さらに1日加えて27日になります。
したがって、eには前の月の日数を使って計算するウが入ります。CAN-MMをすでに1減らしているため、MONTH-ELM(CAN-MM - 1)ではなくMONTH-ELM(CAN-MM)を使います。
f:うるう年かどうかの判定
2月の日数を調整するため、CAN-YYYYを4で割った余りを確認します。割り切れる年は余りが0です。このため、うるう年の判定には余りを表すURU-SUPPLYを使い、URU-SUPPLY = ZEROとします。fはウです。
この処理が対象とする年は2016年〜2099年です。この範囲には、うるう年の判定で例外となる2100年が含まれません。そのため、4で割り切れるかどうかで判定できます。QUOTIENTは割り算の商を表すので、うるう年の判定には使いません。

誤りやすいポイント

  • dをRSV-PROCやCHK-PROCの中に入れると、もう一方の処理を通ったときにキャンセル料の発生開始日を設定できません。両方の処理が終わった後に追加します。
  • eでは、先にCAN-MMを1減らしている点に注意します。MONTH-ELM(CAN-MM)が、さかのぼった先の月の日数を示します。
  • 宿泊日が7日ちょうどの場合も、7日戻ると前の月になります。そのため、前の月に移る条件は「7日より前」ではなく「7日以下」です。
  • うるう年の判定で使うのは、割り算の商ではなく余りです。4で割り切れるかを確認するには、余りが0かどうかを見ます。

FAQ

Q: 予約できなかった場合、なぜキャンセル料の発生開始日を0にするのですか?
A: 予約が成立していないため、キャンセル料が発生する日もありません。追加処理では、PRM-RSLTが0でない場合にPRM-CANCELを0にします。
Q: 2月以外の月でもMONTH-ELMを使うのはなぜですか?
A: 前の月の日数は月によって異なります。MONTH-ELMには各月の日数が用意されているため、月ごとの日数を個別に決め打ちせずに計算できます。
Q: うるう年では、どの部分の日付が変わりますか?
A: 2月の日数が28日から29日になります。そのため、前の月が2月で、うるう年のときだけCAN-DDに1を加えます。

関連キーワード: COBOL、索引ファイル、主キー、日付計算、うるう年

解説を読んでも分からないところは、AIに質問できます。 この問題の本文と解説をふまえて答えます。

この設問をAIに質問する

クイズモードで開きます(AIへの質問は無料の会員登録で使えます)

戦国ITクイズ機能

\ せっかくなら /

基本情報技術者を
クイズ形式で学習しませんか?

クイズ画面へ遷移する→

すぐに利用可能!

©︎2026 情報処理技術者試験対策アプリ

このサイトについてブログプライバシーポリシー利用規約特商法表記開発者について