平成28年秋期試験午前問題 午後問8

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

問8 データ構造及びアルゴリズム

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

 事務計算においては,数値を見やすく表示(印字)するために,例えば3桁ごとに区切りの","を挿入するなどの編集処理がよく行われる。
 関数 Edit は,指定された編集パターンに従って,数値を編集するプログラムである。表1に,関数 Edit を用いた編集例を示す。例1では,3桁ごとに区切りの","を挿入している。例2では,例1の編集に加え,上位の空いた桁を"*"で埋めている。例3では,数値の右端から2桁目と3桁目の間に"."を挿入している。
pm08_1.gif
 ここで,編集パターン中の文字"▯"及び"▮"は,数字と対応付けされた制御文字を表している。また,"␣"は空白文字を表している。

〔プログラムの説明〕
  • 関数 Edit は,次の形式で呼び出され,二つの引数をもつ。
      関数:Edit(文字型: Pattern[],文字型:Value[])
     Pattern[] には,編集パターンの文字列が格納されている。Value[] には,編集する数値を表す文字列が格納されている。各配列の添字は,0から始まる。文字列 Pattern[] のi番目の文字は Pattern[i-1] と表記する。文字列 Value[] についても同様である。
  • Pattern[] は,1文字以上から成る文字列であって,表示可能な図形文字及び制御文字("▯"及び"▮")から構成される。
  • Value[] は,数値を表す文字列であって,数字"0"~"9"の並びの後に,数値が正又は0なら"+"を,負なら"-"を付加した形式である。数字の個数は,Pattern[] 中の文字"▯"及び"▮"の個数と一致するように,必要であれば前方に"0"を付加する。例えば,Pattern[] の内容が"*▯▯,▯▮▯"のとき,Value[] には,数値が123なら"00123+",0なら"00000+",-123なら"00123-"を指定する。
  • 関数 Edit は,Value[] で与えられた数値を Pattern[] に従って編集し,編集結果で Pattern[] を置き換える。
    〔編集方法〕
     Pattern[] 中の各文字について,先頭から順に1文字ずつ,次の①~③のいずれか一つの操作を実行していく。
    1. 関数 Edit が呼び出されたときの Pattern[] 中の先頭の文字(以下,fill文字という)で置き換える。
    2. Value[] 中の対応する桁の数字で置き換える。
    3. 置き換えないで,そのまま残す。
  • 論理型変数 signif は,on 又は off の値を取る。この変数の実行開始時の値は off であり,Value[] 中に最上位から"0"が連続した後に"0"でない数字が見つかると on になる,などの使い方をする。
  • 関数 Edit が呼び出されるとき,各引数には正しい値が設定されているものとする。
pm08_3.gif

設問1

次の記述中の に入れる正しい答えを,解答群の中から選べ。

 引数 Pattern[] 及び Value[] に幾つかのデータを与えて,関数 Edit を実行した結果を,表3に示す。
pm08_4.gif
a に関する解答群
  • "*******#"
  • "********"
  • "******0#"
  • "******0*"
b,c に関する解答群
  • "*****12#"
  • "*****12*"
  • "****.12#"
  • "****.12*"
  • "***0.12#"
  • "***0.12*"
解答選択欄
  • a:
  • b:
  • c:
  • a=
  • b=
  • c=

解説

〔プログラム〕のループは、p=0からはじまり、pがPattern[]の長さ-1より小さい間続きます。つまりパターン文字列を前から1文字ずつ処理していき、最後の文字に至るまで繰り返します。各空欄についてプログラム中の各値と処理内容をトレースしていくと次のようになります。

aについて〕
pm08_8.gif
[ループ前処理]
 fill←*,v←0,signif←off

[ループ処理]
pm08_8a.gif
Pattern[p]が▯と▮以外、かつ signif=off なのでケース8が適用されます。

 Pattern[0]←*(fill文字)
pm08_8b.gif
Pattern[p]が▯で signif=off、さらにValue[v]="0"なのでケース1が適用されます。Pattern[1]にfill文字が格納されるとともにvに1が加えられます。

 Pattern[1]←*,v←0+1
pm08_8c.gif
p=1の場合と同様にケース1が適用されます。

 Pattern[2]←*,v←1+1
pm08_8d.gif
Pattern[p]が▯と▮以外、かつ signif=off なのでケース8が適用されます。

 Pattern[3]←*
pm08_8e.gif
P=1,2の場合と同様にケース1が適用されます。

 Pattern[4]←*,v←2+1
pm08_8f.gif
同様にケース1が適用されます。

 Pattern[5]←*,v←3+1
pm08_8g.gif
同様にケース1が適用されます。

 Pattern[6]←*,v←4+1
pm08_8h.gif
Pattern[p]が▯と▮以外、かつ signif=off なのでケース8が適用されます。

 Pattern[7]←*

Pattern[]に格納されている文字を前から順に並べると「********」になります。

a=イ:********

bについて〕
pm08_9.gif
[ループ前処理]
 fill←*,v←0,signif←off

[ループ処理]
pm08_8a.gif
Pattern[p]が▯と▮以外、かつ signif=off なのでケース8が適用されます。

 Pattern[0]←*(fill文字)
pm08_8b.gif
Pattern[p]が▯で signif=off、さらにValue[v]="0"なのでケース1が適用されます。

 Pattern[1]←*,v←0+1
pm08_8c.gif
p=1の場合と同様にケース1が適用されます。

 Pattern[2]←*,v←1+1
pm08_9d.gif
同様にケース1が適用されます。

 Pattern[3]←*,v←2+1
pm08_9e.gif
Pattern[p]が▯と▮以外、かつ signif=off なのでケース8が適用されます。

 Pattern[4]←*
pm08_9f.gif
Pattern[p]が▯で signif=off、さらにValue[v]="1"なのでケース4または5に該当します。Value[v+1]の値("2")は"+"以外のため、2つのうちケース4が適用されます。この結果、Pattern[5]にValue[v]の値である"1"が格納され、signif=on になります。

 Pattern[5]←1,signif←on,v←3+1
pm08_9g.gif
Pattern[p]が▯で signif=on なのでケース6または7に該当します。Value[v+1]の値("-")は"+"以外のため、ケース6が適用されます。この結果、Pattern[6]にValue[v]の値である"2"が格納されます。

 Pattern[6]←2,v←4+1
pm08_9h.gif
Pattern[p]が▯と▮以外、かつ signif=on なので、パターン文字を"そのまま残す"ケース9が適用されます。

 Pattern[7]←#

Pattern[]に格納されている文字を前から順に並べると「*****12#」になります。

b=ア:*****12#

cについて〕
pm08_10.gif
[ループ前処理]
 fill←*,v←0,signif←off

[ループ処理]
pm08_8a.gif
Pattern[p]が▯と▮以外、かつ signif=off なのでケース8が適用されます。

 Pattern[0]←*(fill文字)
pm08_8b.gif
Pattern[p]が▯で signif=off、さらにValue[v]="0"なのでケース1が適用されます。

 Pattern[1]←*,v←0+1
pm08_8c.gif
p=1の場合と同様にケース1が適用されます。

 Pattern[2]←*,v←1+1
pm08_10d.gif
Pattern[p]が▮で signif=off、さらにValue[v]=0なのでケース2または3に該当します。Value[v+1]の値("1")は"+"以外のため、2つのうちケース2が適用されます。この結果、Pattern[3]にはfill文字が格納され、signif=on になります。

 Pattern[3]←*,signif←on,v←2+1
pm08_10e.gif
Pattern[p]が▯と▮以外、かつ signif=on なので、パターン文字を"そのまま残す"ケース9が適用されます。

 Pattern[4]← .
pm08_10f.gif
Pattern[p]が▯で signif=on なのでケース6または7に該当します。Value[v+1]の値("2")は"+"以外のため、ケース6が適用されます。この結果、Pattern[3]にはValue[v]の値である"1"が格納されます。

 Pattern[5]←1,v←3+1
pm08_10g.gif
Pattern[p]が▯で signif=on なのでケース6または7に該当します。Value[v+1]の値は"+"であるため、ケース7が適用されます。この結果、Pattern[6]にはValue[v]の値である"2"が格納され、signif=off になります。

 Pattern[6]←2,signif←off,v←4+1
pm08_10h.gif
Pattern[p]が▯と▮以外、かつ signif=off なのでケース8が適用されます。

 Pattern[7]←*

Pattern[]に格納されている文字を前から順に並べると「****.12*」になります。

c=エ:****.12*

設問2

次の記述中の に入れる正しい答えを,解答群の中から選べ。

 プログラム中の破線で囲んだ部分の処理(表2のケース1~7の処理)を,詳細なプログラムとして記述すると,次のようになる。
pm08_5.gif
d,e に関する解答群
  • "1"≦Value[v] and Value[v]≦"9"
  • Value[v]="0"
  • Value[v+1]="-"
  • Value[v+1]="+"
  • Value[v+1]≠"-"
  • Value[v+1]≠"+"
解答選択欄
  • d:
  • e:
  • d=
  • e=

解説

eについて〕
先にeについて考えます。

プログラムを見るとe以降の部分は分岐条件「signif=off」が偽であるケースに適用される処理だとわかります。「signif=off」が偽、つまりsignifが"on"になっているケースは表2中のケース6および7だけです。この2つの処理はPattern[p]にValue[v]を代入する操作は同じですが、Value[v+1]の値によってsignifが変わります。signifにoffがセットされるのはValue[v+1]が"+"になっているときなので、eには Value[v+1]="+" の条件式が入ります。

e=エ:Value[v+1]="+"
pm08_11.gif
dについて〕
プログラムを見るとdの分岐条件によってPattern[p]に代入する値がfill文字またはValue[v]に変化しています。前述したとおりdを含む部分はsignifが"off"であるケース1~5に対して行われる操作です。これを踏まえて表2のケース1~5をよく見てみると、Pattern[p]に代入する文字は、Value[v]="0"のケース1~3でfill文字、"1"~"9"のケース4,5ではValue[v]、というようにValue[v]の値によって異なることに気が付きます(下表参照)。式の評価が真であればfill文字が代入されることになるため、dには Value[v]="0" の条件式が入ります。

d=イ:Value[v]="0"
pm08_12.gif

設問3

次の記述中の に入れる正しい答えを,解答群の中から選べ。

 関数 Edit では,例えば,fill文字を"␣"とする編集パターンを指定することによって,数値が正なら"␣␣1,234␣",負なら"␣␣1,234-"と編集することができる。表2のケース1~7のうち,数値が正なら数値の後に続く文字をfill文字で置き換えるために用意されたケースはfである。
f に関する解答群
  • 2,4及び7
  • 3,5及び7
  • 4及び7
  • 5及び7
解答選択欄
  • f:
  • f=

解説

数字以外の文字である符号"+"にはケース8または9が適用されます。このとき"+"がfill文字で置換えられるためにはsignifの値が"off"になっている必要があります。表2を見ると次の文字(Value[v+1])が"+"のときにsignifに"off"をセットするケースは3,5および7の3つです。

しかし、ケース3は"1"~"9"が現れる以前の0埋めの部分をfill文字で置き換えるときだけに適用されるケースです。数値が0でなければ"1"~"9"が必ず一度は現れるため、その時点で前方の"0"をfill文字で置き換える処理は終了します。初めて"1"~"9"が現れたときにはケース4,5のいずれかが適用され、その後に続く数字にはケース6または7が適用される流れになります。

したがって正の数である場合に"+"をfill文字に置き換えるためのケースは「5及び7」が正解です。

f=エ:5及び7

Pagetop