科目B サンプル問題 解説
まーぼさん
★FE シルバーマイスター
(No.1)
需要がありそうなので時間があるときに新しく公開された科目Bのサンプル問題の解説をしていこうと思います。
2023.07.07 15:13
手紙さん
(No.2)
勝手ながら、いまいま知りたい3を切望します、、、
2023.07.07 15:19
ほしかさん
(No.3)
3と6以外不正解だったので、解説あると嬉しいです
お願いします
お願いします
2023.07.07 15:52
まーぼさん
★FE シルバーマイスター
(No.4)
問1 findPrimeNumbers
引数で与えられた整数以下の素数をpnListに格納し、pnListを返す関数。
素数とは、2以上で1と自身でしか割り切れないような数。(2,3,5,7,11...)
divideFlagはtrueなら出力(素数)、falseなら出力しない(素数でない合成数)
ここでbを見ると、divideFlagをfalseに更新するときの条件を考えればいいことが分かる。つまり素数でないことが分かるような条件がbに入る。
bは
・i÷jの余りが0と等しい
・i÷jの商が1と等しくない
のどちらか。
i = 5の場合を考えると、5は素数なのでdivideFlagをfalseに更新したくない。つまり条件bが偽であってほしいということ。
5の正の平方根は2より大きく、3より小さいので、jは2から2まで実行される。
i = 5,j = 2の場合、
・i ÷ jの余りは5 = 2*2 + 1なので1(0と等しくない→bが偽)
・i÷jの商は2(1と等しくない→bが真)
bが偽である方を選ぶので、
bは
・i÷jの余りが0と等しい
aはdivideFlagの初期化の話。maxNumはfindPrimeNumbersの引数。findPrimeNumbers(6)ならば、6以下の素数なので、2,3,5が表示されるべきだが、aをmaxNum +1にすると、i=7のときもdivideFlagがtrueになり表示されてしまうので不適。
よって答えはア。
処理のイメージは
全部の数をとりあえず素数としてみる。(divideFlagをtrueに初期化)
2,3,4…と順々にその数を割っていき、割り切れたら素数ではない(i÷jの余りが0ならばdivideFlagをfalseに更新)
divideFlagがtrueなものは素数として表示。
引数で与えられた整数以下の素数をpnListに格納し、pnListを返す関数。
素数とは、2以上で1と自身でしか割り切れないような数。(2,3,5,7,11...)
divideFlagはtrueなら出力(素数)、falseなら出力しない(素数でない合成数)
ここでbを見ると、divideFlagをfalseに更新するときの条件を考えればいいことが分かる。つまり素数でないことが分かるような条件がbに入る。
bは
・i÷jの余りが0と等しい
・i÷jの商が1と等しくない
のどちらか。
i = 5の場合を考えると、5は素数なのでdivideFlagをfalseに更新したくない。つまり条件bが偽であってほしいということ。
5の正の平方根は2より大きく、3より小さいので、jは2から2まで実行される。
i = 5,j = 2の場合、
・i ÷ jの余りは5 = 2*2 + 1なので1(0と等しくない→bが偽)
・i÷jの商は2(1と等しくない→bが真)
bが偽である方を選ぶので、
bは
・i÷jの余りが0と等しい
aはdivideFlagの初期化の話。maxNumはfindPrimeNumbersの引数。findPrimeNumbers(6)ならば、6以下の素数なので、2,3,5が表示されるべきだが、aをmaxNum +1にすると、i=7のときもdivideFlagがtrueになり表示されてしまうので不適。
よって答えはア。
処理のイメージは
全部の数をとりあえず素数としてみる。(divideFlagをtrueに初期化)
2,3,4…と順々にその数を割っていき、割り切れたら素数ではない(i÷jの余りが0ならばdivideFlagをfalseに更新)
divideFlagがtrueなものは素数として表示。
2023.07.07 16:11
まーぼさん
★FE シルバーマイスター
(No.5)
問2 proc
proc2を実行したときの出力なので、proc2を見ると、
proc2(){
proc3()
Bを出力
proc1()
}
proc2を実行すると、proc3が初めに実行されるのでproc3を見る。proc3はCを出力なので、proc3をCを出力に置き換える。
→
proc2(){
Cを出力
Bを出力
proc1()
}
proc1の部分を置き換える。
→
proc2(){
Cを出力
Bを出力
Aを出力
proc3()
}
proc3の部分を置き換える。
→
proc2(){
Cを出力
Bを出力
Aを出力
Cを出力
}
C,B,A,Cの順に出力されるので答えはク
proc2を実行したときの出力なので、proc2を見ると、
proc2(){
proc3()
Bを出力
proc1()
}
proc2を実行すると、proc3が初めに実行されるのでproc3を見る。proc3はCを出力なので、proc3をCを出力に置き換える。
→
proc2(){
Cを出力
Bを出力
proc1()
}
proc1の部分を置き換える。
→
proc2(){
Cを出力
Bを出力
Aを出力
proc3()
}
proc3の部分を置き換える。
→
proc2(){
Cを出力
Bを出力
Aを出力
Cを出力
}
C,B,A,Cの順に出力されるので答えはク
2023.07.07 16:23
まーぼさん
★FE シルバーマイスター
(No.6)
問3 sort
典型的なクイックソートです。会場でゼロからトレースするのは厳しいと思います。
問題を見て瞬時に
・クイックソートだと分かること
・クイックソートが自分で実行できること
が大切だと思います。
問題としては、クイックソートの一回の処理が終わったあとの出力です。
data = {2,1,3,5,4}
first = 1,last = 5なので、
pivot = data[3] = 3
i = 1
j = 5
pivotの決め方はなんでもいいのですが、配列の真ん中をpivotにするクイックソートのイメージは、昇順ならば「左半分にはpivotよりも小さい値を、右半分にはpivotよりも大きい値をざっくり集める」です。
このイメージが掴めていれば、dataはpivotの値が3でそれより左側には3より小さい値が、それより右側には3より大きい値が既にあるので、1回目のクイックソートではそのままdata = {2,1,3,5,4}と出力されることが分かると思います。
具体的な動作は後に書きます。
典型的なクイックソートです。会場でゼロからトレースするのは厳しいと思います。
問題を見て瞬時に
・クイックソートだと分かること
・クイックソートが自分で実行できること
が大切だと思います。
問題としては、クイックソートの一回の処理が終わったあとの出力です。
data = {2,1,3,5,4}
first = 1,last = 5なので、
pivot = data[3] = 3
i = 1
j = 5
pivotの決め方はなんでもいいのですが、配列の真ん中をpivotにするクイックソートのイメージは、昇順ならば「左半分にはpivotよりも小さい値を、右半分にはpivotよりも大きい値をざっくり集める」です。
このイメージが掴めていれば、dataはpivotの値が3でそれより左側には3より小さい値が、それより右側には3より大きい値が既にあるので、1回目のクイックソートではそのままdata = {2,1,3,5,4}と出力されることが分かると思います。
具体的な動作は後に書きます。
2023.07.07 17:02
ttttttさん
(No.7)
2023年の試験を受けた人に質問です。A問題は、今まで通り過去問道場の問題を解くことが合格の近道だと思いますが、問題の比率としたら知識問題と計算問題どれくらいの比率で出るか知りたいです。B問題は、改正されたと思いますが、サンプル問題を参考にしてやればいいのでしょうか。今年中には、試験を受ける予定なんですが教えていただけると幸いです。お手数ですが宜しくお願い致します。
2023.07.07 17:10
まーぼさん
★FE シルバーマイスター
(No.8)
while(data[i] < pivot)の部分は「左半分からpivotよりも大きい値を探す」
while(pivot < data[j])の部分は「右半分からpivotより小さい値を探す」
に対応すると考えてください。
まず「左半分からpivotより大きい値を探す」をやります。
iは1に初期化されていたので、
i = 1の場合、
data[1] = 2, pivot = 3 の大小を比較します。data[i] < pivotなのでiが1増加します。
i = 2の場合、
data[2] = 1, pivot = 3の大小を比較します。data[i] < pivotなのでiが1増加します。
i = 3の場合、
data[3] = 3, pivot = 3の大小を比較します。data[i] < pivotは偽でwhile(data[i] < pivot)のループは終わります。(左半分からpivotより大きい値が見つけられず、真ん中で処理が止まったイメージ)
次に「右半分からpivotより小さい値を探す」をします。
j = 5に初期化されていたので、
j = 5の場合、
data[5]=4とpivot=3の大小を比較します。pivot < data[j]なのでjが1減少します。
j = 4の場合、
data[4] = 5とpivot= 3の大小を比較します。pivot < data[j]なのでjが1減少します。
j = 3の場合、
data[3] = 3とpivot=3 の大小を比較します。pivot< data[j]が偽なので、while(pivot < data[j])のループは終わります。(右半分からpivotより小さい値が見つけられず、真ん中で処理が止まったイメージ)
i = 3,j = 3でどちらも処理が停止したため、if(i<=j)が真になり、while(true)のループを抜ける。
data[i]とdata[j]の値を入れ替える。i,jはともに3なのでdata[3]とdata[3]を入れ替えるということ。つまり入れ替えていないのと同じ。
後に続く
i = i + 1
j = j - 1
はクイックソートの次の段階のための処理だが、問題では一回目の出力を聞いているので特に考える必要はありません。
while(pivot < data[j])の部分は「右半分からpivotより小さい値を探す」
に対応すると考えてください。
まず「左半分からpivotより大きい値を探す」をやります。
iは1に初期化されていたので、
i = 1の場合、
data[1] = 2, pivot = 3 の大小を比較します。data[i] < pivotなのでiが1増加します。
i = 2の場合、
data[2] = 1, pivot = 3の大小を比較します。data[i] < pivotなのでiが1増加します。
i = 3の場合、
data[3] = 3, pivot = 3の大小を比較します。data[i] < pivotは偽でwhile(data[i] < pivot)のループは終わります。(左半分からpivotより大きい値が見つけられず、真ん中で処理が止まったイメージ)
次に「右半分からpivotより小さい値を探す」をします。
j = 5に初期化されていたので、
j = 5の場合、
data[5]=4とpivot=3の大小を比較します。pivot < data[j]なのでjが1減少します。
j = 4の場合、
data[4] = 5とpivot= 3の大小を比較します。pivot < data[j]なのでjが1減少します。
j = 3の場合、
data[3] = 3とpivot=3 の大小を比較します。pivot< data[j]が偽なので、while(pivot < data[j])のループは終わります。(右半分からpivotより小さい値が見つけられず、真ん中で処理が止まったイメージ)
i = 3,j = 3でどちらも処理が停止したため、if(i<=j)が真になり、while(true)のループを抜ける。
data[i]とdata[j]の値を入れ替える。i,jはともに3なのでdata[3]とdata[3]を入れ替えるということ。つまり入れ替えていないのと同じ。
後に続く
i = i + 1
j = j - 1
はクイックソートの次の段階のための処理だが、問題では一回目の出力を聞いているので特に考える必要はありません。
2023.07.07 17:29
まーぼさん
★FE シルバーマイスター
(No.9)
※訂正
i = 3,j = 3でどちらも処理が停止したため、if(i>=j)が真になり、while(true)のループを抜ける。
i = 3,j = 3でどちらも処理が停止したため、if(i>=j)が真になり、while(true)のループを抜ける。
2023.07.07 17:36
まーぼさん
★FE シルバーマイスター
(No.10)
問3はテキストよりも実際に手を動かしてやってみている動画の方が分かりやすいと思います。
ブンアイさんのクイックソートの動画がおすすめです。
ブンアイさんのクイックソートの動画がおすすめです。
2023.07.07 17:49
まーぼさん
★FE シルバーマイスター
(No.11)
問4 ハッシュの計算とハッシュが衝突したときに再計算する問題ですね。
testを実行したときのHashArrayの中身を問う問題ですので、testをトレースしましょう。
HashArray = {-1,-1,-1,-1,-1}
add(3)を実行
i = calcHash1(3) = 4
HashArray[4] = -1のため、最初のif文を通り、
HashArray[4] = 3
add(3)が終了
add(18)を実行
i = calcHash1(18) = 4
HashArray[4] = 3のため、elseの方を通る。(ハッシュが衝突したため、再計算)
i = calcHash2(18) = 2
HashArray[2] = -1のため、elseの中のif文を通り、
HashArray[2] = 18
add(18)が終了
add(11)を実行
i = calcHash1(11) = 2
HashArray[2] = 18のため、elseの方を通る。
i = calcHash2(11) = 5
HashArray[5] = -1のため、elseの中のif文を通り、
HashArray[5] = 11
add(11)が終了し、testも終了
結局は、HashArrayを5個の-1で初期化しその後
add(3)ではHashArray[4] = 3
add(18)ではHashArray[2] = 18
add(11)ではHashArray[5] = 11
に更新したので
testを実行した後は
HashArray = {-1,18,-1,3,11}となりエが正解。
testを実行したときのHashArrayの中身を問う問題ですので、testをトレースしましょう。
HashArray = {-1,-1,-1,-1,-1}
add(3)を実行
i = calcHash1(3) = 4
HashArray[4] = -1のため、最初のif文を通り、
HashArray[4] = 3
add(3)が終了
add(18)を実行
i = calcHash1(18) = 4
HashArray[4] = 3のため、elseの方を通る。(ハッシュが衝突したため、再計算)
i = calcHash2(18) = 2
HashArray[2] = -1のため、elseの中のif文を通り、
HashArray[2] = 18
add(18)が終了
add(11)を実行
i = calcHash1(11) = 2
HashArray[2] = 18のため、elseの方を通る。
i = calcHash2(11) = 5
HashArray[5] = -1のため、elseの中のif文を通り、
HashArray[5] = 11
add(11)が終了し、testも終了
結局は、HashArrayを5個の-1で初期化しその後
add(3)ではHashArray[4] = 3
add(18)ではHashArray[2] = 18
add(11)ではHashArray[5] = 11
に更新したので
testを実行した後は
HashArray = {-1,18,-1,3,11}となりエが正解。
2023.07.07 18:20
まーぼさん
★FE シルバーマイスター
(No.12)
問5 コサイン類似度の問題ですがコサイン類似度の知識は必要ではなく、コサイン類似度の式とプログラムのどの部分が対応しているかを見抜く問題です。
calcCosineSimilarityのreturnがsimilarityなので、
similarity と問題の中央にある難しそうな式が対応しています。
similarity = numerator / denominator とあるので
コサイン類似度の式の分子がnumeratorに、分母がdenominatorに対応します。
aはnumeratorの計算方法です。分子にはルートや二乗はありませんので、この時点でエ、オ、カに絞れます。
続いてbを考えます。
コサイン類似度の分母は「vector1の各要素の二乗の和の正の平方根」と「vector2の各要素の二乗の和の正の平方根」の積であることが分かります。
2つ目のfor文は全て埋められていて、これが「vector1の各要素の二乗の和の正の平方根」に対応しています。
エは「vector1の各要素の二乗の和の正の平方根」と「vector2の各要素の二乗の和の正の平方根」の”積”
オは「vector1の各要素の二乗の和の正の平方根」と「vector2の各要素の二乗の和の正の平方根」の”和”
カは「vector2の各要素の二乗の和の正の平方根」
をdenominatorに代入する処理になりますから、エが正解です。
calcCosineSimilarityのreturnがsimilarityなので、
similarity と問題の中央にある難しそうな式が対応しています。
similarity = numerator / denominator とあるので
コサイン類似度の式の分子がnumeratorに、分母がdenominatorに対応します。
aはnumeratorの計算方法です。分子にはルートや二乗はありませんので、この時点でエ、オ、カに絞れます。
続いてbを考えます。
コサイン類似度の分母は「vector1の各要素の二乗の和の正の平方根」と「vector2の各要素の二乗の和の正の平方根」の積であることが分かります。
2つ目のfor文は全て埋められていて、これが「vector1の各要素の二乗の和の正の平方根」に対応しています。
エは「vector1の各要素の二乗の和の正の平方根」と「vector2の各要素の二乗の和の正の平方根」の”積”
オは「vector1の各要素の二乗の和の正の平方根」と「vector2の各要素の二乗の和の正の平方根」の”和”
カは「vector2の各要素の二乗の和の正の平方根」
をdenominatorに代入する処理になりますから、エが正解です。
2023.07.07 18:52
まーぼさん
★FE シルバーマイスター
(No.13)
とりあえずアルゴリズムの分野については終わりましたので、質問や間違っているところがあればお願いいたします。、
2023.07.07 19:03
まーぼさん
★FE シルバーマイスター
(No.14)
問3 少し訂正
後に続く
i = i + 1
j = j - 1
はクイックソートの次の段階のための処理だが、問題では一回目の出力を聞いているので特に考える必要はありません。
と書きましたが、
data = {4,5,3,1,2}のように一回目のクイックソートで複数回入れ替えなければならないときは、
i = i + 1
j = j - 1
の更新処理が必要なので、二回目以降のクイックソートを追う必要がなくてもデータの並び順によっては考えなければなりません。
後に続く
i = i + 1
j = j - 1
はクイックソートの次の段階のための処理だが、問題では一回目の出力を聞いているので特に考える必要はありません。
と書きましたが、
data = {4,5,3,1,2}のように一回目のクイックソートで複数回入れ替えなければならないときは、
i = i + 1
j = j - 1
の更新処理が必要なので、二回目以降のクイックソートを追う必要がなくてもデータの並び順によっては考えなければなりません。
2023.07.07 19:56
まーぼさん
★FE シルバーマイスター
(No.15)
問3 訂正
data[i] data[j]の入れ替えの前にループを抜けるので入れ替えは行われない。が正しいですね。
data[i] data[j]の入れ替えの前にループを抜けるので入れ替えは行われない。が正しいですね。
2023.07.07 20:38
まーぼさん
★FE シルバーマイスター
(No.16)
問3 補足
厳密には左からpivot以上、右からpivot以下を探します。
一回目のクイックソートでは
data = {2,1,3,5,4}
をpivot = 3を中心に左には3未満の数、右には3以上の数が来るように並び変えますが、既に満たしているのでそのまま出力れます。
厳密には左からpivot以上、右からpivot以下を探します。
一回目のクイックソートでは
data = {2,1,3,5,4}
をpivot = 3を中心に左には3未満の数、右には3以上の数が来るように並び変えますが、既に満たしているのでそのまま出力れます。
2023.07.07 20:59
手紙さん
(No.17)
ありがとうございます!!再度解いてみます!!
2023.07.08 14:32
まーぼさん
★FE シルバーマイスター
(No.18)
手紙さん
他のことと並行しつつ書いたので、訂正ばかりで申し訳ないです…
問3はdataの並び順がたまたま一回目の出力でそのままの並びで出力されるような並びだったというのが重要です。
data = {4,5,3,1,2}で与えられていた場合は、同じプログラムでも1回目の出力でそのまま出力されるわけではなく、data = {2,1,3,5,4}と出力されます。
他のことと並行しつつ書いたので、訂正ばかりで申し訳ないです…
問3はdataの並び順がたまたま一回目の出力でそのままの並びで出力されるような並びだったというのが重要です。
data = {4,5,3,1,2}で与えられていた場合は、同じプログラムでも1回目の出力でそのまま出力されるわけではなく、data = {2,1,3,5,4}と出力されます。
2023.07.08 14:53
手紙さん
(No.19)
>>まーぼさん
私の勘違い失礼しました、了解です。丁寧にありがとうございます!!!
2023.07.08 22:50
手紙さん
(No.20)
>まーぼさん
早速全問理解することができました。
おかげ様です。
またテキストに戻って前進したいと思います!!
またわからないことがあたらまーぼさんにききたいです。。。!!
今後ともよろしくお願いいたします。
※※
コサイン類似度は、英単語の意味と式との照らし合わせができれば、ものの5秒でたぶん解ける一番簡易な問題ですね。。重めのトレース問題よりよほど簡易かと、ある意味(この問題を落としたらNGと)愕然とします、、
2023.07.09 15:15
まーぼさん
★FE シルバーマイスター
(No.21)
手紙さん
ありがとうございます!私でよければいつでも聞きに来てください!
ありがとうございます!私でよければいつでも聞きに来てください!
2023.07.09 17:14
ほしかさん
(No.22)
>まーぼさん
私の理解不足なのですが
問4の以下部分がなぜ4になるかわかりません。
教えていただけないでしょうか
>>add(3)を実行
i = calcHash1(3) = 4
2023.07.10 13:47
やさん
(No.23)
問4のadd(3)を実行した際に
i = calcHash1(3) = 4
であることがよくわからないのですが、解説お願いでいませんでしょうか
i = calcHash1(3) = 4
であることがよくわからないのですが、解説お願いでいませんでしょうか
2023.07.10 13:57
やさん
(No.24)
この投稿は投稿者により削除されました。(2023.07.10 14:15)
2023.07.10 14:15
まーぼさん
★FE シルバーマイスター
(No.25)
>ほしかさん
calcHash1(value)は
(value mod HashArrayの要素数) + 1を返します。
value = 3,HashArrayの要素数 = 5ですから
(3 mod 5) + 1になります。
(3 mod 5)は3を5で割った余りで、3になってこれに1をたすので(3 mod 5) + 1 = 4です。よってcalcHash1(3) = 4となります。
※3を5で割った余りについて補足
17を5で割った余り
→17 = 5*3 + 2で2のように求めます。
同じようにやると
3 = 5*0 + 3で3と求められます。
(nで割った余り)は0~(n-1)までの範囲ということに注意してください。
3 = 5*1 -2 で-2と考えることもできるかもしれませんが、5で割った余りは0から4までしか値として取れないので、3が正しいです。
2023.07.10 14:12
ほしかさん
(No.26)
>まーぼさん
なるほど!!わかりやすい説明ありがとうございます!!
2023.07.10 14:15
70yoldさん
(No.27)
この”新しく公開された科目Bのサンプル問題”はどこに掲載されているのでしょうか? IPA HPのサンプル問題には見あたらないのですが。
2023.07.15 13:30
70yoldさん
(No.28)
この投稿は投稿者により削除されました。(2023.07.15 13:33)
2023.07.15 13:33
70yoldさん
(No.29)
見つかりました。公開問題(問題冊子・解答例)ですね。お騒がせしました。
2023.07.15 14:11
まーぼさん
★FE シルバーマイスター
(No.30)
www.ipa.go.jp/shiken/mondai-kaiotu/sg_fe/koukai/2023r05.html
URLを貼っておきます
URLを貼っておきます
2023.07.16 15:25
広告
返信投稿用フォーム
スパム防止のためにスレッド作成日から30日経過したスレッドへの投稿はできません。
広告