基本情報技術者試験のサンプル問題を解こう!(16)(科目B)「五数要約」

スポンサーリンク
IT系

基本情報技術者試験のサンプル問題(科目B)を解いてみよう。

今回のテーマは、「五数要約」である。

〔プログラム〕 
○実数型: findRank(実数型の配列: sortedData, 実数型: p) 
整数型: i 
i ← (p × (sortedDataの要素数 - 1)) の小数点以下を切り上げた値 
return sortedData[i + 1] 

○実数型の配列: summarize(実数型の配列: sortedData) 
実数型の配列: rankData ← {}  /* 要素数0の配列 */ 
実数型の配列: p ← {0, 0.25, 0.5, 0.75, 1} 
整数型: i 
for (i を 1 から pの要素数 まで 1 ずつ増やす) 
 rankDataの末尾 に findRank(sortedData, p[i])の戻り値 を追加する 
endfor 
return rankData 

解答群
ア {0.1, 0.3, 0.5, 0.7, 1}
イ {0.1, 0.3, 0.5, 0.8, 1}
ウ {0.1, 0.3, 0.6, 0.7, 1}
エ {0.1, 0.3, 0.6, 0.8, 1}
オ {0.1, 0.4, 0.5, 0.7, 1}
カ {0.1, 0.4, 0.5, 0.8, 1}
キ {0.1, 0.4, 0.6, 0.7, 1}
ク {0.1, 0.4, 0.6, 0.8, 1}

正解:ク

この問題は、昇順に並んだデータに対して、特定の「五数要約(minimum, Q1, median, Q3, maximum)」を求める関数 summarize の動作を理解することが問われている。


まずは「要点」を整理しよう

関数 summarize({0.1, 0.2, ..., 1.0}) を呼び出すと、以下の5つのパーセンタイルに対応する値を返す仕組みになっている。

パーセンタイルとは
パーセンタイルとは、データを小さい順に並べたときに、全体の何%の位置にあるかを示す指標。

p = {0, 0.25, 0.5, 0.75, 1}

なお、それぞれの意味は以下の通りである。

p値意味
0最小値 (min)
0.25第1四分位数 (Q1)
0.5中央値 (median)
0.75第3四分位数 (Q3)
1最大値 (max)

findRank 関数の動作

i ← ceil(p × (要素数 - 1))
return sortedData[i + 1]

与えられた p に対して、次のようにインデックスを求めて、配列からその値を返している。
配列 sortedData は次の 10 要素である。

{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}  1   2   3   4   5   6  7    8   9  10  ← 添字(1から開始)

ここで、sortedData の要素数を「N」とする。

たとえば要素が10個あるとき、隣り合う要素の間にある区間は9個になる。
この「区間の位置」を基準にしてパーセンタイルの位置を計算するために、N - 1 を使う。
つまり、要素数 N = 10 ならば N - 1 = 9 となり、パーセンタイルの位置は p × 9 で求められる。

このとき、計算された位置が小数(例:2.25)の場合は、実際の配列のインデックスに対応させるために 切り上げ(ceil() を使い、最も近い上側の整数位置を選ぶ。

設問の「i ← (p × (sortedDataの要素数 - 1)) の小数点以下を切り上げた値」のうち、「小数点以下を切り上げた値」は、この ceil() を日本語で表現していると読み取れる。
本解説でも ceil()を使用して説明する。
※ceil 関数は、与えられた浮動小数点数を切り上げて、最も近い整数を返す関数である。
C言語やC++で使用する場合は、<math.h> ヘッダーをインクルードする必要がある。

また、配列のインデックスは1から始まるため、最終的に参照するのは i + 1 番目の要素になる。

それぞれの p に対して何が返るかを計算してみよう。


各 p に対して findRank の計算をしよう

① p = 0

  • i = ceil(0 × 9) = ceil(0) = 0
  • return sortedData[0 + 1] = sortedData[1] = 0.1

② p = 0.25

  • i = ceil(0.25 × 9) = ceil(2.25) = 3
  • return sortedData[3 + 1] = sortedData[4] = 0.4

③ p = 0.5

  • i = ceil(0.5 × 9) = ceil(4.5) = 5
  • return sortedData[5 + 1] = sortedData[6] = 0.6

④ p = 0.75

  • i = ceil(0.75 × 9) = ceil(6.75) = 7
  • return sortedData[7 + 1] = sortedData[8] = 0.8

⑤ p = 1

  • i = ceil(1 × 9) = ceil(9) = 9
  • return sortedData[9 + 1] = sortedData[10] = 1.0

戻り値 rankDataを確認しよう

{0.1, 0.4, 0.6, 0.8, 1}

選択肢の中では、
ク {0.1, 0.4, 0.6, 0.8, 1} であり、
正解となる。

まとめ

  • 五数要約は、 Min(最小),Q1, median, Q3, Max(最大)の5つの代表値のこと。
  • 本問は五数要約をパーセンタイルに基づいて抽出する処理である。
  • p = {0, 0.25, 0.5, 0.75, 1} に対応する値を出力することで、五数要約をプログラム的に理解していることが求められる。

C言語のコードで本問を確認してみよう!

#include <stdio.h>

#define SIZE 10

// 手動で ceil を再現する関数(整数切り上げ)
int manualCeil(double value) {
    int intPart = (int)value;
    if (value > (double)intPart) {
        return intPart + 1;
    } else {
        return intPart;
    }
}

// findRank関数:pに対応する値を返す
double findRank(double sortedData[], int size, double p) {
    double position = p * (size - 1);
    int i = manualCeil(position);
    return sortedData[i];
}

// summarize関数:五数要約を求める
void summarize(double sortedData[], int size, double rankData[]) {
    double p[] = {0.0, 0.25, 0.5, 0.75, 1.0};
    for (int i = 0; i < 5; i++) {
        rankData[i] = findRank(sortedData, size, p[i]);
    }
}

int main() {
    double sortedData[SIZE] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0};
    double rankData[5];

    summarize(sortedData, SIZE, rankData);

    printf("五数要約: {");
    for (int i = 0; i < 5; i++) {
        printf("%.1f", rankData[i]);
        if (i < 4) printf(", ");
    }
    printf("}\n");

    return 0;
}

実行結果

五数要約: {0.1, 0.4, 0.6, 0.8, 1.0}

manualCeil() 関数は、ceil() の代わりに小数点以下を判定して切り上げる処理をしている。
<math.h>を使わないことで、幅広い環境で動作する。

コメント

タイトルとURLをコピーしました