平成28年度秋期午後のアルゴリズム問題である問8の私の解き方・考え方について解説していきます。
問題
IPAの公式サイトで公開されています。このページでは問8についての解説を行います。
https://www.jitec.ipa.go.jp/1_04hanni_sukiru/mondai_kaitou_2016h28_2/2016h28a_fe_pm_qs.pdf
問題の概要
問題としては与えられた数列を指定されたパターンに応じて編集するというものです。正直どういうところでこういう編集の仕方をするのかがイメージつきません…。
スポンサーリンク
設問1
設問1は実例をプログラムに当てはめて処理した時の結果が問われる問題です。
最初にプログラムのポイントを見ておきましょう。青枠内は各変数の初期化処理です。fillにPattern配列の先頭の文字が格納されるところがポイントです。vはValueの添字になります。
緑枠の判断ではPattern[p]が□もしくは▪️の場合のみ表2のケースごとの処理が行われ、ピンク枠ないでValue配列の添字であるvが1増やしています。逆に緑でNoで判断されればvはそのまま変化しません。オレンジ枠はsignifがoffの場合にPattern[p]にfillを代入する処理になります。
表2は下記のようになります。↑の点線部の処理が行われる際はPattern[p]、signif、Value[v]、Value[v+1]それぞれの値によってどのケースに当てはまるかを考え、そのケースに応じて更新処理列の処理を実行してやる必要があります。
それでは実際にプログラムに表3のパターンと数字の配列を入力した時にどう動くか追っていきましょう。ここでは[ c ]の場合について説明しようと思います。
プログラムの青枠が終了した時点の各変数は以下のようになります。
Pattern[]:”*□□▪️.□□#”
Value:”00012+”
fill:*
signif:off
v:0
p;0
・p=0の時
Pattern[0]は□と▪️以外、signifはoffなので、ケース8となります。ですのでPattern[0]にはfillの値が格納されます。signifはoffのままです。vはPattern[0]が□と▪️以外なので0のままです。ですので、p=0の時のループが完了した時は各変数は下記のようになります。
Pattern[]:”*□□▪️.□□#”
Value:”00012+”
fill:*
signif:off
v:0
p:0
・p=1の時
Pattern[1]は□、signifはoff、value[0]は0なので、ケース1となります。ですのでPattern[1]にはfillの値が格納されます。signifはoffのままです。vはPattern[1]が□ですので+1されます。p=1の時のループが完了した時は各変数は下記のようになります。
Pattern[]:”**□▪️.□□#”
Value:”00012+”
fill:*
signif:off
v:1
p:1
・p=2の時
p=1の時と全く同じ考えで更新が行われます。p=2の時のループが完了した時は各変数は下記のようになります。
Pattern[]:”***▪️.□□#”
Value:”00012+”
fill:*
signif:off
v:2
p:2
・p=3の時
Pattern[3]は▪️、signifはoff、value[2]は0、value[3]は+以外なのでケース2となります。ですのでPattern[3]にはfillの値が格納されます。signifはonに変化します。。vはPattern[3]が▪️ですので+1されます。p=3の時のループが完了した時は各変数は下記のようになります。
Pattern[]:”****.□□#”
Value:”00012+”
fill:*
signif:on
v:3
p:3
・p=4の時
Pattern[4]は”.”、signifはonなのでケース9となります。ですのでPattern[4]は変更されません。signifもonのままです。vはPattern[4]が”.”ですのでこれもそのままです。。p=4の時のループが完了した時は各変数は下記のようになります。
Pattern[]:”****.□□#”
Value:”00012+”
fill:*
signif:on
v:3
p:4
・p=5の時
Pattern[5]は□、signifはon、value[3]は1、value[4]は+以外なのでケース6となります。ですのでPattern[5]にはvalue[3]の値(1)が格納されます。signifはonのままです。vはPattern[5]が□ですので+1されます。p=5の時のループが完了した時は各変数は下記のようになります。
Pattern[]:”****.1□#”
Value:”00012+”
fill:*
signif:on
v:4
p:5
・p=6の時
Pattern[6]は□、signifはon、value[4]は2、value[5]は+なのでケース7となります。ですのでPattern[6]にはvalue[4]の値(2)が格納されます。signifはoffに変化します。vはPattern[6]が□ですので+1されます。p=6の時のループが完了した時は各変数は下記のようになります。
Pattern[]:”****.12#”
Value:”00012+”
fill:*
signif:off
v:5
p:6
・p=7の時
Pattern[7]は#、signifはoff、value[5]は+なのでケース8となります。ですのでPattern[7]にはfillの値(*)が格納されます。signifはoffのままです。vはPattern[7]が□ですので+1されます。p=7の時のループが完了した時は各変数は下記のようになります。
Pattern[]:”****.12*”
Value:”00012+”
fill:*
signif:off
v:5
p:7
これでこの具体例での処理は終了です。
[ c ]はこの時のPattern[]の値を文字列を選べば良いので[ c ]の答えはPattern[]:”****.12*”となります。 [ a ]と[ b ]も同様にpの値を増やしながらどのケースに当てはまるかを考えて更新処理を実行していけば答えは導けます。[ a ]の答えはPattern[]:”********”で、[ b ]の答えはPattern[]:”*****12#” になります。
設問2
設問2は穴埋め問題です。
条件分岐がいくつかありますが、下の図のようにどのケースの時にそのプログラムが実行されるかをはっきりさせておけば答えを考えるのが楽になると思います。
下の図はよりわかりやすくなるように点線四角部分の直前の条件分岐も書いてます(緑枠部分)。この条件により「点線四角部分はケース1からケース7のみ実行」されることになります。また青枠の条件分岐により、「上側(条件がYES)はケース1からケース5」が、「下側(条件がNO)はケース6からケース7」のみが実行されることになります。この限定されたケースの中で、さらに条件分岐をどう設定すれば表2通りの動きができるかを考えることで答えが導け出せます。
まず[ d ]を見てみましょう。[ d ]が成立するとかはPattern[p]にfillが、成立しない時にPattern[p]にValue[v]が格納されることが分かります。
ここで表2のケース1からケース5から、Pattern[p]をfillに更新する処理を行うケースを探してみましょう。
ケース1からケース3が当てはまりますね。ですのでケース1からケース3でのみ成立し、ケース4からケース5でのみ成立しない条件が[ d ]の答えになります。
表2からその条件を考えてみましょう。ケース1からケース3はValue[v]が”0″の時のケースで、ケース4からケース5はValueが”1″〜”9″の時のケースとなっていますので、「Value[v]が”0″である」を条件としてやれば表2の通りの動きとなります。
したがって[ d ]の答えはValue[v]=”0″となります。
[ e ]に関しても同様にして解くことができます。[ e ]はケース6とケース7の時のみ実行される部分ですので、この2つの中で、signifをoffに更新するケースを見つけてみましょう。ケース7ですね。あとはケース7でのみ成立し、ケース6でのみ成立しない条件が[ e ]の答えとなります。「Value[v+1]が”+”」がこの条件になります。
したがって[ e ]の答えはValue[v+1]=”+”となります。
設問3
この設問はあるケースに当てはまるケースを答える問題です。そのケースとは「数値が正なら数値の後に続く文字をfill文字で置き換えるために用意されたケース」です。
「数値が正なら」があるのでValueが”+”かどうかが関わってきそうです。
実際にValue[v+1]=”+”のケースであるケース3とケース5とケース7を見てみると全て更新処理でsingifをoffに設定しています。こうなると、次のPatter[p]が□でも▪️以外でもない場合はPattern[p]にfillに更新されますので、これらのケースが「文字をfill文字で置き換えるために用意されたケース」の候補になりそうです。
ただし、実はケース3は「数値の後に続く文字をfill文字で置き換えるために用意されたケース」ではありません。なぜならケース3はまだ数値が出てきていない場合のみに実行されるケースのためです。「数値の後に続く文字」という部分に当てはまりません。ですので[ f ]の答えはケース5とケース7となります。
スポンサーリンク
解いてみた感想
問題なんか微妙じゃないですかね・・・。なんか使い所のよく分からない問題ですし。設問3は引っ掛けというか意地悪な問題でケース3も解答に含める人多そうでした。
ただ設問3が意地悪な分、設問1と設問2は簡単に思えました。
設問1は問題に示されたPatternとValueを実際にプログラムに入力した時にどう動くかを追えば解けますし、追うのも単純なので解きやすいと思います。
設問2は穴埋めですが条件文を考えれば良いだけですので表2と照らしわせて考えれば解けると思います。
問題のとっつきにくさと問題の難しさはあまり相関が無いと思います。問題の意味が分からなくてもプログラムの説明の1文1文をプログラムに照らし合わせて考えればほとんどの問題を正解に導けます。
★オススメページ★
下記ページから他の回の解説もたどれます。他の回のアルゴリズム問題の解き方がわからない場合は是非読んでみてください!
本ページの図・プログラム・問題文について
図やプログラム、問題文はIPA公開の過去問題から引用しています。また図やプログラムに関しては説明に必要な部分に関してのみ加工して使用させていただいております。
出典:平成28年度 秋期 基本情報技術者試験(FE)試験区分 午後 問8
アルゴリズム問題の対策(PR)
過去問を解いてみて感触はいかがだったでしょうか?
全く分からなかった...という方もいらっしゃるかもしれません。はっきりいってアルゴリズム問題は、特に慣れないと難易度は高いです。
なので、こういった方にはもっと "簡単なアルゴリズム問題を解いて慣れていく" ことをオススメします。で、この簡単なアルゴリズム問題を解くのにオススメの本が下記の うかる! 基本情報技術者 [午後・アルゴリズム編] です。
オススメする理由は、特に本の前半部分で難易度の低いアルゴリズムの紹介や解説が行われているところです。こういったアルゴリズムの動作などを実際にトレースして追ってみたりすることで簡単な問題からアルゴリズム問題に慣れていくことができます。
また、「アルゴリズムとは?」といったアルゴリズム入門から解説してくれているので、プログラミングをやったことない方にも親切な内容になっています。
アルゴリズム問題に全く手がつかないというような方は、まずは上記のような本でアルゴリズムに慣れるのがオススメです。
慣れてきたら、あとは実際の過去問を解いて "さらに考える力を養う" & "実際のアルゴリズム問題に慣れる" のが良いと思います。
私のサイトでも過去問の解説をしていますので是非参考にしてください。私の解説だけでなく、他の人の解説も参考にしたいような場合には、下記のような過去問の参考書もオススメです(アルゴリズム問題だけでなく、全問題の解説も充実しています)。
p=5 に関して
ドットコムでも見たのですが、
Pattern[5]は□、signifはon、value[3]は1、value[4]は+以外なので
の部分で、ケース6に当たるのではないでしょうか?
gg さん
コメントありがとうございます!
ご指摘の通り、ケース6が正しいです。p=3 の時の部分のコピペが残ってしまっていました…。
早速修正させていただきました。
ご指摘大変ありがとうございます。大変助かりました。