令和6年度 科目B 問5
アルゴリズム
配列に関する問題
次のプログラム中の[a]~[c]に入れる正しい答えの組合せを,解答群の中から選べ。ここで,配列の要素番号は1から始まる。
一度の注文で購入された商品のリストを,注文ごとに記録した注文データがある。表に,注文データの例を示す。
表 注文データの例
| 注文番号 | 購入された商品のリスト |
|---|---|
| 1 | A, B, D |
| 2 | A, D |
| 3 | A |
| 4 | A, B, E |
| 5 | B |
| 6 | C, E |
注文データから,商品xと商品yとが同一の注文で購入されやすい傾向を示す関連度L_xyを,次の式で計算する。
L_xy = (M_xy × 全注文数) / (K_x × K_y)
ここで,M_xyは商品xと商品yとが同一の注文で購入された注文数,K_xは商品xが購入された注文数,K_yは商品yが購入された注文数を表す。表の例では,M_ABが2,全注文数が6,K_Aが4,K_Bが3であるので,商品Aと商品Bの関連度L_ABは,(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の値をこの順にコンマ区切りで出力する
解答群は原典では a・b・c の組合せの表。
- アa:arrayK[i] / b:arrayM[i] / c:allItemsの要素数
- イa:arrayK[i] / b:arrayM[i] / c:ordersの要素数
- ウa:arrayK[i] / b:arrayM[i] / c:otherItemsの要素数
- エa:arrayM[i] / b:arrayK[i] / c:allItemsの要素数
- オa:arrayM[i] / b:arrayK[i] / c:ordersの要素数
- カa:arrayM[i] / b:arrayK[i] / c:otherItemsの要素数
答えと解説を見る
✓ これが正解オa:arrayM[i] / b:arrayK[i] / c:ordersの要素数
解説
aは同時購入の数arrayM、bは購入注文数arrayK、cは全注文数です。
関連度の式 L_xy = (M_xy × 全注文数) / (K_x × K_y) と、プログラムの最後のforにある valueL ← (arrayM[i] × [c]) ÷ (itemCount × arrayK[i]) を並べると、arrayMがM_xy、itemCountがK_x、arrayKがK_yに当たることが分かります。軸になるのは、二重のifのどちらの段で数えるかと、全注文数を表すものは何かの二つです。
内側のforでは、注文がotherItems[i]を含むときに外側のifに入ります。さらに引数のitemも含むときだけ実行されるのが[a]なので、二つの商品が同じ注文に入っている数M_xyを数えるarrayM[i]が入ります。itemの有無に関係なく実行される[b]は、otherItems[i]を含む注文の数K_yを数えるarrayK[i]です。全注文数は注文データの配列ordersの要素数で、これが[c]に入ります。
itemに“A”を与えて追うと、otherItemsは{“B”, “C”, “D”, “E”}、itemCountは4です。全6件を処理すると、arrayMは{2, 0, 2, 1}、arrayKは{3, 1, 2, 2}になります。Bの値は (2 × 6) ÷ (4 × 3) = 1.0 で、問題文の例と一致します。Dは (2 × 6) ÷ (4 × 2) = 1.5、Eは0.75、Cは0なので、Dと1.5が出力されます。
見分け方は、二つの商品がそろったときだけ数える内側の段がM、片方を含むだけで数える外側の段がKと、式の記号に当てはめることです。
ほかの選択肢はなぜ違うのか
- 項番a:[a]はitemとotherItems[i]が同じ注文に両方含まれるときだけ通る場所なので、M_xyを数えるarrayM[i]が入ります。ここにarrayK[i]を置くと、arrayK[i]が同時購入の数、arrayM[i]が商品yの購入注文数を数えることになり、式のM_xyとK_yが分子と分母で入れ替わった値になります。
- 項番b:[b]はotherItems[i]を含む注文であれば、itemを含むかどうかを問わず通ります。数えているのは商品yが買われた注文数K_yなのでarrayK[i]です。arrayM[i]を置くと、itemを含まない注文まで同時購入として数えてしまいます。
- 項番c:[c]は全注文数で、注文データの配列ordersの要素数、表の例では6です。allItemsの要素数は商品の種類数の5、otherItemsの要素数はitemを除いた4なので、どちらを使ってもL_ABが1.0になりません。
出典:令和6年度 基本情報技術者試験 科目B 問5
この解説に誤りを見つけたら教えてください。直して、直した記録を残します。誤りを報告する(メールが開きます)