基本情報技術者 2011年 春期 午後 問10
次のCOBOLプログラムの説明及びプログラムを読んで、設問1,2に答えよ。
〔プログラムの説明〕
小売業のC社では、自社株主へ株主優待として、自社店舗で利用できる商品券を発行することにした。株主の保有株数と保有期間によって、発行額を決定する。この会社では、毎年3月31日の株取引終了時点で自社株を保有している株主を対象とした株主一覧を作成しており、商品券は、2011年3月31日に作成した株主一覧に登録されている個人株主に対して発行する。
このプログラムは、株主ファイルを読み込み、発行する商品券の発行額を商品券ファイルに出力する。
(1) 株主ファイルは、2011年3月31日に作成した株主一覧に登録されている個人株主を対象に作成した、図1に示すレコード様式の順ファイルである。

① 株主番号には、株主に対して一意に割り当てた番号が設定されている。
② 保有株数には、保有する株数が設定されている。保有株数の最大は999,999とする。
③ 登録年には、最初に株主一覧に登録された年が設定されている。ただし、株をすべて売却した後に再取得した株主の場合は、再取得後、株主一覧に登録された年が設定される。
(2) 保有期間は、登録年から2011年までの年数で決定する。例えば、登録年が2006年の場合は5年である。
(3) この会社が株式公開したのは1990年4月1日であり、最初に株主一覧へ登録されるのは1991年3月31日である。したがって、最長保有期間は20年である。
(4) 商品券ファイルは、図2に示すレコード様式の順ファイルである。

発行額には、各株主に対する商品券の発行額を設定する。発行額は、表1に示す決定表によって決まる。


設問1:
問題文を見る プログラム中のに入れる正しい答えを、解答群の中から選べ。
a, bに関する解答群
ア:1
イ:9
ウ:10
エ:99
オ:999
カ:1000
キ:ANY
ク:OTHER
c〜eに関する解答群
ア:0
イ:1
ウ:4
エ:5
オ:9
カ:10
キ:ANY
ク:OTHER
f, gに関する解答群
ア:1000
イ:3000
ウ:5000
エ:9999
オ:10000
カ:20000
キ:ANY
ク:OTHER
模範解答
a:ア、b:オ、c:ア、d:ウ、e:キ、f:ア、g:エ
解説
解答の導き方
まず、プログラムが商品券の発行額を決める基準を整理します。表1では、保有株数を3区分、保有期間を2区分に分けています。
プログラムでは、30行目の「BASE-YEAR - HLD-YEAR」で保有期間を計算します。BASE-YEARは2011なので、例えば登録年が2006年なら、となります。したがって、5年未満は0年から4年、5年以上は5年から20年です。
31行目のEVALUATEは、HLD-STOCK(保有株数)とTERM(保有期間)を順に調べる条件分岐です。ALSOでつないだ条件は、1つ目が保有株数、2つ目が保有期間に対応します。また、THRUは範囲を表し、両端の値も範囲に含みます。
この対応から、まず次の値が分かります。
- 保有株数が999以下の範囲は、1 THRU 999です。よって、aは1、bは999です。
- 保有期間が5年未満の範囲は、0 THRU 4です。よって、cは0、dは4です。
- 保有株数が1,000 ~ 9,999株の範囲は、1000 THRU 9999です。よって、fは1000、gは9999です。
残るeにはANYが入ります。ANYは「どの値でもよい」という意味です。5年以上を直接表す値ではありませんが、WHENの条件は上から順に調べられます。そのため、先に5年未満の条件に当てはまった場合は、その後のANYには進みません。
WHENの並びを確認すると、次のように表1の条件を実現しています。
- 32行目は、保有株数が1~999で、保有期間が0~4の場合です。ここで1,000円を設定します。
- 34行目は、保有株数が1~999で、保有期間はANYです。ただし、5年未満は先に32行目で処理されます。したがって、ここではその残りである5年以上の場合に3,000円を設定します。
- 35行目は、保有株数が1,000~9,999で、保有期間が0~4の場合です。ここでも3,000円を設定します。
- 37行目は、保有株数が1,000~9,999で、保有期間はANYです。5年未満は先に35行目で処理されるため、残る5年以上の場合に5,000円を設定します。
- 38行目は、保有株数がANYで、保有期間が0~4の場合です。保有株数が999以下の場合と1,000~9,999の場合は先に処理されるため、ここでは10,000株 以上の場合に5,000円を設定します。
- 40行目は、保有株数も保有期間もANYです。先に処理されていない組合せ、つまり10,000株 以上で5年以上の場合に10,000円を設定します。
このように、eをANYにすることで、前のWHENで処理した条件を除いた残りのケースを受け持たせています。
誤りやすいポイント
- eを「5」と考えないようにします。5年以上の条件を、5 THRU 20のように書いているのではありません。ANYで広く指定し、先にある条件に一致したものを除いた残りを処理しています。
- ANYを使った条件は、前の条件と重なることがあります。その場合も、WHENは上から順に評価されるので、最初に一致した条件の動作が実行されます。
- 5年未満は「5年以下」ではありません。5年ちょうどは5年以上に含まれ、保有期間の範囲では0~4年と5年以上に分かれます。
- 保有株数の区分を取り違えないようにします。999株以下の次は1,000~9,999株、その次は10,000株以上です。
FAQ
Q: ANYは、保有期間が5年以上であることを直接表していますか?
A: いいえ。ANYは、どの値でもよいという指定です。先に5年未満の条件が評価されるため、該当するANYの条件では、その残りである5年以上を処理できます。
A: いいえ。ANYは、どの値でもよいという指定です。先に5年未満の条件が評価されるため、該当するANYの条件では、その残りである5年以上を処理できます。
Q: THRUで指定した範囲の端の値は含まれますか?
A: はい。例えば1 THRU 999は、1と999を含む範囲です。
A: はい。例えば1 THRU 999は、1と999を含む範囲です。
Q: 38行目の保有株数がANYなら、999株以下の株主にも適用されませんか?
A: 38行目までに該当する条件が先に評価されます。999株以下で保有期間が0~4なら32行目、1,000~9,999株で保有期間が0~4なら35行目が先に一致するため、38行目はそれらに当てはまらない株主に適用されます。
A: 38行目までに該当する条件が先に評価されます。999株以下で保有期間が0~4なら32行目、1,000~9,999株で保有期間が0~4なら35行目が先に一致するため、38行目はそれらに当てはまらない株主に適用されます。
関連キーワード: COBOL、EVALUATE文、条件分岐、範囲指定、順ファイル
設問2:
問題文を見る 保有期間の傾向を確認するため、商品券の発行額の算出と同時に、図3に示す棒グラフを表示するようプログラムを変更したい。表2中のに入れる正しい答えを、解答群の中から選べ。
〔グラフの説明〕
(1) 行の先頭に表示してある数字は、保有期間を表す。
(2) “*”は、当該保有期間に該当する株主比率を表す。
(3) 株主比率は、2%未満の端数を切り捨て、“*”一つを2%として表示する。
(4) 目盛りの数字の単位は10%である。


hに関する解答群
ア:ADD 1 TO CNT-HLD(CNT)
イ:ADD 1 TO CNT-HLD(CNT + 1)
ウ:ADD 1 TO CNT-HLD(CNT - 1)
エ:ADD 1 TO CNT-HLD(TERM)
オ:ADD 1 TO CNT-HLD(TERM + 1)
カ:ADD 1 TO CNT-HLD(TERM - 1)
iに関する解答群
ア:COMPUTE RATIO = (CNT-ALL * 100 / CNT-HLD(CNT)) / 2
イ:COMPUTE RATIO = (CNT-ALL * 100 / CNT-HLD(CNT + 1)) / 2
ウ:COMPUTE RATIO = (CNT-ALL * 100 / CNT-HLD(CNT - 1)) / 2
エ:COMPUTE RATIO = (CNT-HLD(CNT) * 100 / CNT-ALL) / 2
オ:COMPUTE RATIO = (CNT-HLD(CNT + 1) * 100 / CNT-ALL) / 2
カ:COMPUTE RATIO = (CNT-HLD(CNT - 1) * 100 / CNT-ALL) / 2
模範解答
h:オ、i:オ
解説
解答の導き方
この変更では、株主ごとの商品券の発行額を計算する処理に加えて、保有期間ごとの株主数も数えます。その株主数から、図3の棒グラフに表示する「*」の数を求めます。
まず、保有期間は行番号30で、2011からHLD-YEARを引いて求めています。たとえば、登録年が2006なら、保有期間は5年です。この値がTERMに入ります。
表2で追加するCNT-HLDは、保有期間ごとの株主数を記録する配列です。配列は、同じ種類の値を複数まとめて扱うためのものです。CNT-HLD OCCURS 21なので、添字(配列の中の位置を表す番号)は1から21までです。一方、保有期間は0年から20年までです。
そのため、保有期間と配列の添字は次のように対応させます。
株主1人分の処理が終わるたびに、その人の保有期間に対応するCNT-HLDを1増やす必要があります。保有期間はTERMに入っており、配列の添字は保有期間より1大きいので、追加する処理はADD 1 TO CNT-HLD(TERM + 1)です。したがって、hはオです。
同じ処理でCNT-ALLも1増やします。これは、株主全体の人数です。CNT-HLDには保有期間ごとの人数、CNT-ALLには全体の人数が入ります。
次に、グラフを表示する処理を考えます。CNTは0から20まで変化し、グラフの各行に表示する保有期間を表します。たとえばCNTが0なら、表示対象は0年の株主です。このとき参照する配列の位置はCNT-HLD(CNT + 1)となります。CNTが0から20までのどの場合も、保有期間に対応する配列の位置を正しく選べます。
CNT-HLD(CNT + 1)に入っている株主数を、CNT-ALLで割ると、その保有期間の株主比率が求められます。百分率にするには100を掛けます。さらに、「*」一つを2%として表示するため、2で割ります。したがって、RATIOを求める式は次の形です。
RATIO = (CNT-HLD(CNT + 1) × 100 ÷ CNT-ALL) ÷ 2
たとえば、ある保有期間の株主比率が7%なら、7を2で割った結果は3.5です。RATIOは小数部分のない項目なので、端数を切り捨てて3となり、「*」を3個表示します。これは「2%未満の端数を切り捨て」という条件に合います。よって、iもオです。
なお、CNT-ALLが0のときは比率の計算で0除算が起きます。そのため、表2ではCNT-ALLが0でない場合にだけGRAPH-PROCを実行するようにしています。
誤りやすいポイント
- CNT-HLDの添字は1から始まります。保有期間が0年のときにCNT-HLD(0)を使うのではなく、CNT-HLD(1)を使います。そのため、添字にはTERM + 1を指定します。
- hとiでは、同じCNT-HLDを使いますが、添字のもとになる変数が異なります。hでは株主ごとの保有期間を表すTERMを使い、iではグラフ表示中の保有期間を表すCNTを使います。
- 株主比率を求めるときは、保有期間ごとの人数を全株主数で割ります。全株主数を保有期間ごとの人数で割ると、求める比率になりません。
- 「*」一つが2%なので、百分率にした後に2で割ります。100で割る必要はありません。
- 棒グラフに表示する「*」の数は、比率を2で割った値の端数を切り捨てたものです。
FAQ
Q: CNT-HLD(TERM + 1)とCNT-HLD(CNT + 1)は、なぜ両方とも「+ 1」するのですか?
A: TERMやCNTは保有期間を0から20で表しますが、CNT-HLDの添字は1から21です。保有期間に対応する位置を選ぶため、どちらも1を足します。
A: TERMやCNTは保有期間を0から20で表しますが、CNT-HLDの添字は1から21です。保有期間に対応する位置を選ぶため、どちらも1を足します。
Q: CNT-ALLは、なぜ株主ごとに1増やすのですか?
A: CNT-ALLは全株主数を表します。株主ファイルの1レコードを処理するたびに1増やすことで、比率計算の分母となる人数を数えます。
A: CNT-ALLは全株主数を表します。株主ファイルの1レコードを処理するたびに1増やすことで、比率計算の分母となる人数を数えます。
Q: 株主が0人の場合は、なぜグラフを表示しないのですか?
A: 株主比率を求める式では、全株主数CNT-ALLで割ります。CNT-ALLが0だと割り算ができないため、グラフ表示の処理を行わないようにしています。
A: 株主比率を求める式では、全株主数CNT-ALLで割ります。CNT-ALLが0だと割り算ができないため、グラフ表示の処理を行わないようにしています。
関連キーワード: 配列、添字、カウンタ、整数除算、百分率աճ



