基本情報技術者試験過去問 令和6年度(2024年)科目B問5
次のプログラム中のa~cに入れる正しい答えの組合せを,解答群の中から選べ。ここで,配列の要素番号は1から始まる。
一度の注文で購入された商品のリストを,注文ごとに記録した注文データがある。表に,注文データの例を示す。

注文データから,商品xと商品yとが同一の注文で購入されやすい傾向を示す関連度Lxyを,次の式で計算する。

ここで,Mxyは商品xと商品yとが同一の注文で購入された注文数,Kxは商品xが購入された注文数,Kyは商品yが購入された注文数を表す。表の例では,MABが2,全注文数が6,KAが4,KBが3であるので,商品Aと商品Bの関連度LABは,(2 ×6) / (4 × 3) = 1.0である。
手続putRelatedItemは,大域変数ordersに格納された注文データを基に,引数で与えられた商品との関連度が最も大きい商品のうちの一つと,その関連度を出力する。プログラムでは,商品は文字列で表し,注文は購入された商品の配列,注文データは注文の配列で表している。注文データには2種類以上の商品が含まれるものとする。また,注文データにある商品以外の商品が,引数として与えられることはないものとする。
-----------
〔プログラム〕
// 注文データ(ここでは表の例を与えている)
大域: 文字列型配列の配列: orders ← {{"A", "B", "D"}, {"A", "D"}, {"A"},
{"A", "B", "E"}, {"B"}, {"C", "E"}}
○putRelatedItem(文字列型: item)
文字列型の配列: allItems ← ordersに含まれる文字列を重複なく辞書順に格納した配列
// 表の例では {"A", "B", "C", "D", "E"}
文字列型の配列: otherItems ← allItemsの複製から値がitemである要素を除いた配列
整数型: i, itemCount ← 0
整数型の配列: arrayK ← {otherItemsの要素数個の0}
整数型の配列: arrayM ← {otherItemsの要素数個の0}
実数型: valueL, maxL ← -∞
文字列型の配列: order
文字列型: relatedItem
for (orderにordersの要素を順に代入する)
if (orderのいずれかの要素の値がitemの値と等しい)
itemCountの値を1増やす
endif
for (iを1からotherItemsの要素数まで1ずつ増やす)
if (orderのいずれかの要素の値がotherItems[i]の値と等しい)
if (orderのいずれかの要素の値がitemの値と等しい)
aの値を1増やす
endif
bの値を1増やす
endif
endfor
endfor
for (iを1からotherItemsの要素数まで1ずつ増やす)
valueL ← (arrayM[i] × c) ÷ (itemCount × arrayK[i])
/* 実数として計算する */
if (valueLがmaxLより大きい)
maxL ← valueL
relatedItem ← otherItems[i]
endif
endfor
relatedItemの値とmaxLの値をこの順にコンマ区切りで出力する
-----------

選択肢
- ア
- イ
- ウ
- エ
- オ
- カ
正解と解き方・学習ポイント(AI解説)
関連度Lxyは、Lxy = (Mxy × 全注文数) ÷ (Kx × Ky) で計算します。プログラムでは、itemが商品x、otherItems[i]が商品yに相当します。
内側のif(itemも同じ注文に含まれる)で増やすのは、xとyが同一注文に含まれた回数Mxyなので「a」はarrayM[i]です。外側のif(otherItems[i]が注文に含まれる)で増やすのは、商品yが含まれる注文数Kyなので「b」はarrayK[i]です。式中の全注文数はordersの要素数なので「c」はordersの要素数です。よって正解は「オ」です。
Point
関連度Lxyの式にある各値(Mxy、Kx、Ky、全注文数)を、プログラム中の変数(arrayM、itemCount、arrayK、ordersの要素数)と正しく対応付けられることを確認することが目的です。特に、if文の入れ子でどの条件のときにどのカウントを増やしているかを読み取れるかが問われます。
解くために必要な知識
この問題を解くには、関連度の式と、注文データをループで数える処理の対応関係を理解している必要があります。
用語の整理
関連度Lxy
商品xと商品yが同一注文で購入されやすい傾向を表す値です。
-
計算式
- Lxy = (Mxy × 全注文数) ÷ (Kx × Ky)
Mxy、Kx、Ky、全注文数
| 記号 | 意味 |
|---|---|
| Mxy | 商品xと商品yが同一の注文で購入された注文数 |
| Kx | 商品xが購入された注文数 |
| Ky | 商品yが購入された注文数 |
| 全注文数 | 注文データに含まれる注文の総数 |
プログラム上の数え方
どこでMxyを数えるか
次の条件を両方満たすときに1増やすのがMxyです。
-
注文にotherItems[i]が含まれる
-
注文にitemが含まれる
このため、入れ子の内側のifで増える変数がMxyに対応します。
どこでKyを数えるか
注文にotherItems[i]が含まれるときに1増やすのがKyです。
このため、外側のifで増える変数がKyに対応します。
全注文数の取り方
注文データはorders(注文の配列)なので、全注文数はordersの要素数です。
問題の解法手順
解く手順
1. 関連度の式を確認する
Lxy = (Mxy × 全注文数) ÷ (Kx × Ky) です。
2. プログラムの変数を式の記号に対応付ける
| 式の記号 | 意味 | プログラム内の対応 |
|---|---|---|
| x | 引数で与えられた商品 | item |
| y | item以外の各商品 | otherItems[i] |
| Kx | xが購入された注文数 | itemCount |
| Ky | yが購入された注文数 | arrayK[i] |
| Mxy | xとyが同一注文で購入された注文数 | arrayM[i] |
| 全注文数 | 注文の総数 | ordersの要素数 |
3. a、bがどのカウントを増やすかを読む
内側のifは「otherItems[i]が含まれる」かつ「itemも含まれる」なので、同一注文で買われた回数Mxyを数えます。よってaはarrayM[i]です。
外側のifは「otherItems[i]が含まれる」なので、商品yが買われた注文数Kyを数えます。よってbはarrayK[i]です。
4. cが何を表すかを読む
valueL ← (arrayM[i] × c) ÷ (itemCount × arrayK[i]) を、Lxy = (Mxy × 全注文数) ÷ (Kx × Ky) に合わせると、cは全注文数なのでordersの要素数です。
選択肢ごとの解説
- ア:不正解
内側のifはMxy(同一注文で購入された注文数)を数える必要がありますが、aがarrayK[i]だとKyを増やすことになり不一致です。またcがallItemsの要素数であり、全注文数になりません。よって誤りです。
- イ:不正解
cがordersの要素数である点は全注文数として適切です。しかしaがarrayK[i]、bがarrayM[i]となっており、同時購入回数Mxyと購入回数Kyの対応が逆になるため、定義式どおりに計算できません。よって誤りです。
- ウ:不正解
aとbの役割が逆で、内側のifで数えるべきMxyをarrayK[i]で数えることになります。またcがotherItemsの要素数であり、全注文数になりません。
- エ:不正解
aとbは正しい対応ですが、cがallItemsの要素数であり、全注文数になりません。よって誤りです。
- オ:正解
aがarrayM[i]でMxyを数え、bがarrayK[i]でKyを数え、cがordersの要素数で全注文数を表します。Lxy = (Mxy × 全注文数) ÷ (Kx × Ky) に一致するので正解です。
- カ:不正解
aとbは正しい対応ですが、cがotherItemsの要素数であり、全注文数になりません。よって誤りです。
まとめ
関連度Lxyは、Lxy = (Mxy × 全注文数) ÷ (Kx × Ky) で計算します。プログラムでは、itemが商品x、otherItems[i]が商品yに相当します。
内側のif(itemも同じ注文に含まれる)で増やすのは、xとyが同一注文に含まれた回数Mxyなので「a」はarrayM[i]です。外側のif(otherItems[i]が注文に含まれる)で増やすのは、商品yが含まれる注文数Kyなので「b」はarrayK[i]です。式中の全注文数はordersの要素数なので「c」はordersの要素数です。よって正解は「オ」です。
内側のifはMxy(同一注文で購入された注文数)を数える必要がありますが、aがarrayK[i]だとKyを増やすことになり不一致です。またcがallItemsの要素数であり、全注文数になりません。よって誤りです。
cがordersの要素数である点は全注文数として適切です。しかしaがarrayK[i]、bがarrayM[i]となっており、同時購入回数Mxyと購入回数Kyの対応が逆になるため、定義式どおりに計算できません。よって誤りです。
aとbの役割が逆で、内側のifで数えるべきMxyをarrayK[i]で数えることになります。またcがotherItemsの要素数であり、全注文数になりません。
aとbは正しい対応ですが、cがallItemsの要素数であり、全注文数になりません。よって誤りです。
aがarrayM[i]でMxyを数え、bがarrayK[i]でKyを数え、cがordersの要素数で全注文数を表します。Lxy = (Mxy × 全注文数) ÷ (Kx × Ky) に一致するので正解です。
aとbは正しい対応ですが、cがotherItemsの要素数であり、全注文数になりません。よって誤りです。