【問1】令和5年度 基本情報技術者試験 科目B 公開問題 を深堀りする
案内人の加藤です🥕
本日は基本情報技術者試験科目Bの公開問題、問1の解説記事になります!
解き方や考え方のイロハを踏まえて解説を行います!
ちょこっと復習
問題の中身を深掘りする際に、少し復習です!
関数名や変数名のネーミング
関数の名前や変数は、その持っている機能にあったネーミングがされています!また、そのようなネーミングをする事を実際に開発する際には心がけなくてはいけません!
例えば、sortという関数は、英語のsortという意味を持っており、sortとは
です。ですので、sortという名前の関数がある場合、「データを並び替える関数なんだな!」と理解することができます!
このように、変数名や関数名は意味があるので、意識していただけるとプログラム全体を理解しやすくなります!
※ もちろん、都合により意味の無い変数名にせざるを得ない場合もあります。
関数
関数は引数(入力)を受け取り、何かを返す(出力)するものです!
問題を解く際には、問題文から何が入力され、何が出力されるかを意識することで、プログラム全体の把握と、解答の候補の絞り込みが可能になります!
変数
変数は、値を入れる箱になります!
おもにプログラム内で用いるデータです。この変数に何が入るのかを意識する事で、プログラム全体の把握と、解答の候補の絞り込みが可能になります!
素数
素数とは、「1とそれ以外の数で割りきれない整数」になります。日本語だと気持ち悪いので、具体例を挙げていきましょう。
2, 3, 5, 7, 9, 11, 13, 17,….
このような数です!(※1は特別で、これは素数ではありません。よく1を素数に含める方がいらっしゃいますが、1は入りません。)
違いとしては、素数かどうか判定する際に使う数が素数だと理解していただくと良いです。どんな数も1で割っちゃうと全て割り切れます。それだと、素数かどうか判別できませんよね?
ですので、チェックする素数かどうかわからない整数以下でわかっている素数を使って割り切れるかどうかを確認すれば大丈夫です!
例えば、17が素数かどうかに関しては、2, 3, 5, 7, 9, 11, 13で割れるか確認すれば良いです。
例えば4は素数では無いですが、4で割り切れるならば、素数である2でも割り切れますよね?だって4は素数の2をすでに持っているからです!
一番重要なことは、「ある正の数の素数の判定は、ある正の数未満で1以外の数で割り切れなければ素数で、割り切れる数があると、素数では無いのです。」
補足:では素数でないものはなんて言う?⇒合成数
4や10のような数は2で割り切れます。このように、1とその数自身以外の正の整数で割り切れる数は合成数と呼ばれます。
つまり、正の整数は合成数と素数に振り分けることができます!
フラグ/フラッグ/Flag/旗
あるときには旗をあげ、そうでない時は旗を下げるときに使います。
これが結構役に立つんです!
まずは問題とにらめっこ
関数findPrimeNumbersは、PrimeNumbers(素数)をfind(見つける)関数になります!
引数は探索する整数の範囲の上限で、出力は素数のみが入った配列になります!
では、中身を見ていきましょう!
プログラム
まずは、見るべき変数の定義や関数についてです。
関数findPrimeNumbersの”()”の中が引数
⇒ つまり、関数の引数で与える整数はmaxNumである。
整数型の配列pnListは空の配列。(これは何?)
整数型i, j。(これは何?)
論理型divideFlag。(これは何?)
という感じで、プログラム内での引数や出力、変数の定義部分を確認しました。ここまでで、わかることは、関数の引数くらいです。
あとは、下に行きつつ、何の処理をしているかを確定させていきます。
まずは、一段目のfor文の条件を見ていきましょう。
" i を2から(a)まで増やす "と。ここで、iが何かを確定できそうです!
iは整数型で、2から(a)まで1ずつ増えていくそうです。
そして、解答の(a)を見ると、引数で与えるmaxNumあるいはmaxNum+1で、これ以下の整数全てに対して素数判定を行います。
つまり、問題の素数かどうかを探索する範囲の変数をiがになっているのです!
ですので、maxNum+1なんか選んでしまうと、問題文と違う事をやることになります。だって、探索の上限は入力のmaxNumなんですもの!
ここまでで、(a)の確定を行う事ができました!
続いては、二段目のfor文になります。
ここでは、素数の探索手法の内、全数探索よりも効率的な解法でプログラムが書かれています。
「え、何それ?」
となるかもしれませんが、今回の解答には余り影響しません。見かけだっましです!
ただ、ココで扱っている整数型jの役割をしっかり見ておかなければ成りません。
注目していただきたいことは、jがこのfor文よりも下で出現していないことです。また、jはiと同じく1ずつ増えているという事がポイントです。
出現しないものをわざわざ書くのはおかしいので、おそらく(b)で使うのでしょう!
if文の中を見てみましょう。
if文の条件文が成立した場合に、dividFlagにfalseが立ちます。そして、二つ目の繰り返し処理を終了していますね!
ただ、dividFlagが何かわからないので、このif文を見てもよくわかりません。
dividFlagとは何かを確定しなければ成りません。
一度休憩
maxNumは問題で与えられている探索範囲の最大値
pnListはまだわからない。
iは素数かどうか未定の整数で、探索範囲の整数。
jはiと同じく1ずつ増えていく変数です。ただ詳細は不明。
dividFlagは論理型であるが、何を判定してるか不明。
という感じです。半分まで来て、iとmaxNumしかわかっていないという、チョやばい展開です😰
ただ焦ることはありません!最後まで見ていきましょう!
では続き
次のif文を見ていきましょう。すると、「dividFlagがtrueと等しい」とあります。そして、dividFlagがtrue出会った場合に起きる処理が、「pnListの末尾にiの値を追加する」です!
要は、このif文を追加する際に、dividFlagにtrueが入ったままであれば、iをpnListの末尾に追加することになります。
iは探索範囲の整数でしたので、dividFlagにtrueであるという事が重要になってきそうです。
そして、最後の文の「return pnList」に注目してください。これは関数の出力になります。pnListが出力なようです!
問題文に戻ると、出力は「全ての素数だけを格納 した配列を返す関数である。」でした。
つまり、pnListは素数だけが入っている事がわかります!
そして、pnListに入るかどうかの条件式をif文の中身である「(divideFlag が true と等しい)」で判別しています!
dividFlagがtrue ⇒ 素数ですよ!
dividFlagがfalse ⇒ 素数ではないですよ!
dividFlagが、素数かどうかの旗振り役をしている事がわかりますし、一段目のfor文では、dividFlagがtrueに、つまり、全て素数であるという旗を揚げていることがわかります。
では、一つ目のif文に戻りましょう。
if文の条件式である(b)が成り立つときに、dividFlagにfalseが入っていますね。ということは…
(b)には、素数では無いと言えるきっかけになる条件式が入り、素数では無いと判断する際には、探索している整数(今回はi)が1以上i未満の整数(今回はj)で割り切れてしまう(あまりがゼロになる)事になります!
ここまで来れば、選択肢は 「i÷jの余りが0と等しい」が解答になります!
選択肢は"ア"が解答になります!
おわりに
基本情報技術者は、コーディング経験の無い方も受けられることが多く、B科目は鬼門になってくると思います。
コーディング経験のある方は、ここまで深掘りして解答を導く必要はありません。ですので、「どのように考えて行けば、回答欄が絞ることができるか」を身につけていただく事が大切です。
また、わかった気になることが最も無意味な行為です。わからない事は理解できるまで考えましょう。間違ってもChatGPTに聞いて納得しては駄目です!
そのために、この記事が役に立っていただければ幸いです🥕