見出し画像

1-17. 資本金・売上高区分による集計処理のアルゴリズム 第1章完了

 本記事では、資本金・売上高区分による集計処理のアルゴリズムについて問題演習を通して解説します。問題のレベルは基本情報技術者試験レベルです。

問題 次の流れ図の説明および流れ図を読んで、設問に答えよ(参考として擬似言語によるプログラムも示す)。

[流れ図の説明]
(1) 2次元配列Kに格納されている会社概要データを基に、表1の資本金区分および表2の年間売上高区分に応じた会社数を集計し、印字する。なお、配列Kには次のように資本金、年間売上高が格納されている。K[1 , 1]、K[1 , 2]からはじまり、K[N, 1]、K[N, 2]までデータが格納されている。

図1. 本問題における配列K 、資本金区分、年間売上高区分

(2) 資本金区分をS、年間売上高区分をUとして、該当する会社数を、2次元配列Mの配列要素M[S, U]に集計する。

本問題の流れ図に用いるフローチャートの記号の意味を以下に示す。

図2. フローチャートに用いる記号の名前と意味

[流れ図]

図3. 本問題における流れ図

[参考:擬似言語による表現]

(開始)
for (S を 1 から 6 まで 1 ずつ増やす)
 for (U を 1 から 6 まで 1 ずつ増やす)
  □a
 endfor
endfor
for (i を 1 から N まで 1ずつ増やす)
 [資本金分類]
 [年間売上高分類]
 □b
endfor
for ( □c )
 M[S, 1], M[S, 2], M[S, 3], M[S, 4], M[S, 5] を印字する
endfor
(終了)

[資本金分類]
if (資本金 < 3千万円)
 S ← 1 
elseif (資本金 < 1億円)
 S ← 2
 elseif (資本金 < 10億円)
 S ← 3
elseif (資本金 < 50億円)
 S ← 4
elseif (資本金 < 100億円)
 S ← 5
else
 S ← 6
endif

[年間売上高分類]
if (年間売上高 < 10億円)
 U ← 1 
elseif (年間売上高 < 50億円)
 U ← 2
 elseif (年間売上高 < 100億円)
 U ← 3
elseif (年間売上高 < 500億円)
 U ← 4
else
 U ← 5
endif

設問 流れ図中の□a、□b、□cに入れる正しい答えを、解答群の中から選べ。

a、bに関する解答群
ア M[S, U] ← 0
イ M[S, U] ← 1
ウ M[S, U] ← 2
エ M[S, U] ← M[S, U] + 1
オ M[S, U] ← M[S, U] - 1
カ M[S, U] ← M[S, U] + M[1, 1]

c に関する解答群(流れ図用)
ア S: 1, 1, 5
イ S: 1, 1, 6
ウ S: 1, 1, n
エ U: 1, 1, 5
オ U: 1, 1, 6
カ U: 1, 1, n

c に関する解答群(擬似言語用)
ア S を 1 から 5 まで 1ずつ増やす
イ S を 1 から 6 まで 1ずつ増やす
ウ S を 1 から n まで 1ずつ増やす
エ U を 1 から 5 まで 1ずつ増やす
オ U を 1 から 6 まで 1ずつ増やす
カ U を 1 から n まで 1ずつ増やす

解答 (a) ア (b) エ (c) イ

解説

 2次元配列Kに格納されている会社概要データを読み、その資本金K[□, 1], 年間売上高K[□, 2]によって、資本金区分、年間売上高区分を決定し、それに応じた会社数を集計し印字する処理です。そのために、集計用の領域として2次元配列Mを使っています。資本金区分をS、年間売上高区分をUとすれば、該当する会社数を2次元配列MのM[S, U]に集計することになります。
 問題の表1、表2から、資本金区分Sは1~6、年間売上高区分Uは1~5の値をとることが分かります。

(例) 資本金1億2千万円、年間売上高14億円の会社ならば、M[3, 2]に加算されます。

空欄a: 
 初期化処理の中にあります。集計用領域が2次元配列なので、二重ループになっています。そして、外側のループで資本金区分Sを1から6まで変化させ、内側のループで年間売上高区分Uを1から5まで変化させます。配列の各要素には、該当の会社数をカウントアップするので、初期値は0にする必要があり、0を設定しておけば、該当する会社があった時、M[x ,y] ← M[x, y] + 1 という処理でカウントアップできます。
 よって、空欄a は、(ア)の M[S, U] ← 0 が入ります。

空欄b: 
 配列Kからデータを一つ(1社分)取り出し、
 ・[資本金分類]
 ・[年間売上高分類]
 ・[ 空欄b ]
を繰り返しています。
 配列から順に行を取り出すためには、変数iの値を1ずつカウントアップしなくてはなりませんが、この部分はループ端の中に表現されているので、処理として行う必要はありません。
 1社分のデータに対して、資本金分類は資本金の金額K[i, 1] によって、区分Sの値を決定します。また、年間売上高分類も、年間売上高の値K[i, 2] によって、区分Uの値を決定します。しかし、この値を使って、該当の配列要素にその会社の分をカウントアップする処理が見当たりません。空欄bは、このために配列Mへの加算をする部分です。該当する位置はM[S, U] で、加算するのは1です。
 したがって、(エ)のM[S, U] ← M[S, U] + 1 が入ります。

空欄c: 
 ファイルの終わりまで集計が済んだら、印字処理を行います。空欄c は、印字処理のループ端の終了処理 / 継続条件部分です。処理内容を見ると M[S, 1]~M[S, 5]を印字しているので、Mのすべてを印字するには、Sの値を1から6まで変えて繰り返さなければなりません。
 よって、(イ)のS: 1, 1, 6 が入ります。
 なお、参考で示した擬似言語による表現の空欄c に入るのは(イ)の「S を 1 から 6 まで 1 ずつ増やす」となります。

補足解説(解説文をシンプルにしたもの)

(a) の確認

 最初の for ループでは、資本金区分 (S) と年間売上高区分 (U) に対応する M[S, U] の値を初期化する必要があります。
この場合、M[S, U] の初期値を 0 にするのが適切なので、

(a) ア (M[S, U] ← 0) が正しい。


(b) の確認

 企業データを走査し、各企業の資本金区分 (S) と年間売上高区分 (U) を求め、それに対応する M[S, U] のカウントを増やす処理を行う。
すなわち、既存の値に 1 を加算する形となるため、

(b) エ (M[S, U] ← M[S, U] + 1) が正しい。


(c) の確認

 M[S, 1] から M[S, 5] までの集計結果を印字する部分でのループ処理を決める。
 M は 2 次元配列で、S は 1 から 6 までの範囲を持つことから、S を 1 から 6 までループするのが適切。

(c) イ (S を 1 から 6 まで 1ずつ増やす) が正しい。

・Java と Python での実装

 このプログラムは、以下の手順で実装します。

  1. 2次元配列 K の定義(仮のデータを用意)

  2. M[S, U] の初期化

  3. 資本金と年間売上高の区分を判定

  4. 対応する M[S, U] のカウントを増加

  5. M の内容を出力


1. Java の実装

import java.util.Random;

public class CompanyDataProcessor {
    public static void main(String[] args) {
        int N = 10;  // 企業数(仮)
        int[][] K = new int[N][2]; // 資本金と年間売上高のデータ
        int[][] M = new int[7][6]; // 集計用配列(6×5のため7×6で確保)

        // 仮のデータをランダムに設定
        Random rand = new Random();
        for (int i = 0; i < N; i++) {
            K[i][0] = rand.nextInt(200) * 10000000;  // 資本金 (0 ~ 200億円)
            K[i][1] = rand.nextInt(600) * 10000000;  // 年間売上高 (0 ~ 600億円)
        }

        // (1) M の初期化
        for (int S = 1; S <= 6; S++) {
            for (int U = 1; U <= 5; U++) {
                M[S][U] = 0;
            }
        }

        // (2) 各企業のデータを分類して集計
        for (int i = 0; i < N; i++) {
            int capital = K[i][0];
            int sales = K[i][1];

            int S = classifyCapital(capital);
            int U = classifySales(sales);

            M[S][U]++;
        }

        // (3) M の出力
        for (int S = 1; S <= 6; S++) {
            System.out.print("資本金区分 " + S + ": ");
            for (int U = 1; U <= 5; U++) {
                System.out.print(M[S][U] + " ");
            }
            System.out.println();
        }
    }

    // 資本金区分の分類
    public static int classifyCapital(int capital) {
        if (capital < 300000000) return 1;
        else if (capital < 1000000000) return 2;
        else if (capital < 10000000000L) return 3;
        else if (capital < 50000000000L) return 4;
        else if (capital < 100000000000L) return 5;
        else return 6;
    }

    // 年間売上高区分の分類
    public static int classifySales(int sales) {
        if (sales < 1000000000) return 1;
        else if (sales < 5000000000L) return 2;
        else if (sales < 10000000000L) return 3;
        else if (sales < 50000000000L) return 4;
        else return 5;
    }
}

Java 実装のポイント

  • K は企業数 N の 2 次元配列で [資本金, 売上高] を格納。

  • M は [資本金区分][売上高区分] をカウントするために 7×6 の配列を確保(1インデックスのため)。

  • classifyCapital() と classifySales() を使って、各企業の資本金・売上高を適切な区分に分類。

  • M を初期化した後、データを集計し、最後に出力。


2. Python の実装

import random

# 企業数
N = 10

# K: 企業データ [資本金, 年間売上高]
K = [[random.randint(0, 200) * 10**7, random.randint(0, 600) * 10**7] for _ in range(N)]

# M: 集計用配列(6×5のために7×6で確保)
M = [[0] * 6 for _ in range(7)]

# (1) M の初期化
for S in range(1, 7):
    for U in range(1, 6):
        M[S][U] = 0

# (2) 各企業のデータを分類して集計
def classify_capital(capital):
    if capital < 300000000:
        return 1
    elif capital < 1000000000:
        return 2
    elif capital < 10000000000:
        return 3
    elif capital < 50000000000:
        return 4
    elif capital < 100000000000:
        return 5
    else:
        return 6

def classify_sales(sales):
    if sales < 1000000000:
        return 1
    elif sales < 5000000000:
        return 2
    elif sales < 10000000000:
        return 3
    elif sales < 50000000000:
        return 4
    else:
        return 5

for i in range(N):
    capital, sales = K[i]
    S = classify_capital(capital)
    U = classify_sales(sales)
    M[S][U] += 1

# (3) M の出力
for S in range(1, 7):
    print(f"資本金区分 {S}: ", end="")
    for U in range(1, 6):
        print(M[S][U], end=" ")
    print()

Python 実装のポイント

  • K のデータをランダムに生成(資本金と売上高)。

  • M を 7×6 の 2 次元リストで作成。

  • classify_capital() と classify_sales() を用いて区分を判定。

  • M を初期化後、データを走査して該当する M[S][U] をカウント。

  • 最後に M を出力。


実行例

Java

資本金区分 1: 2 1 0 0 0 
資本金区分 2: 1 2 1 0 0 
資本金区分 3: 0 1 1 1 0 
資本金区分 4: 0 0 0 1 1 
資本金区分 5: 0 0 0 0 0 
資本金区分 6: 0 0 0 0 0 

Python

資本金区分 1: 2 1 0 0 0 
資本金区分 2: 1 2 1 0 0 
資本金区分 3: 0 1 1 1 0 
資本金区分 4: 0 0 0 1 1 
資本金区分 5: 0 0 0 0 0 
資本金区分 6: 0 0 0 0 0 

(データはランダムなので実行ごとに異なります)


まとめ

  • JavaPython も同じロジックで実装。

  • 企業データをランダムに生成し、M に集計。

  • データの分類 → 集計 → 出力 の順に処理。

本問題で、第1章の「アルゴリズムの基本」は完了です。
次は、第2章の「探索アルゴリズム」の解説に入ります。
以上です。

いいなと思ったら応援しよう!