メインコンテンツへスキップ
見出し画像

【擬似言語⑤課題3❸】最頻値 | 方式❸リスト登録しながら数える(基本情報技術者, 科目B, アルゴリズム)

    このNoteでは「最頻値」を求める擬似言語を作ります。

    3つ方式を考えついたので全3回になります。分かり易い回から学習しても大丈夫ですよ。ご自分でも「{1, 2, 4, 2}って4枚のカードが1枚ずつ手元に来た時に、一番枚数の多い数字をどう調べるか」手順を考えて見てくださいね。

    1つめ。部屋を準備して入ってもらう感じ。データによっては空室も残ります。>【擬似言語⑤課題3❶】最頻値 | 方式❶binを準備して数えるNote

    画像

    2つめ。予め並べてから数える方式。>【擬似言語⑤課題3❷】最頻値 | 方式❷ソート後に数えるNote

    画像

    今回。3つめ(今回のNote)。都度部屋を追加しながら数える方式。私が手作業でやるならこの手順かなぁ。>【擬似言語⑤課題3❸】最頻値 | 方式❸リスト登録しながら数えるNote(今回)

    画像

    それでは始めましょう!


    >全Noteへのリンク(FE節)
    ※科目Aのテーマ別/科目B/旧FE午後など沢山作りました!


    方式3 | 初登場時に数える部屋を用意する

    考えは、「初登場」したら「数を記録する部屋を用意」しながら、数え足していく感じ。

    画像

    「1が初めて来たな、1を数える部屋を用意しよう。2が初めて~用意しよう。4が~用意しよう。2は既に部屋があるから、部屋作りは不要で数え足そう」という動き。




    関数流用 | すでに部屋があるか/ないか

    すでに部屋を準備してる/してないかの判定は、以前作った「getIndexInArray関数」を使います。>【擬似言語⑪課題】重複排除のNote*

    配列arrayに値targetが含まれていれば、arrayの要素番号を返します。含まれてなければ、-1を返します。

    ○整数型: getIndexInArray(実数型の配列: array, 実数型: target)
      整数型: i
      整数型: length ← arrayの要素数
    
      for (i を 1 から length まで 1 ずつ増やす)
        if (array[i] と target が等しい)
          return i
        endif
      endfor
    
      return -1
    end

    例えばarray={3, 4}でtarget=3なら、array[1]なので1が返り。target=4なら、2が返り。target=1なら-1が返ります。




    手順をプログラム的表現に落とし込む

    擬似言語向けに手順を分解して考えます。

    画像

    繰り返しループになるように意識して書き出しますね。

    配列frequencyに個数を記録。

    1. データ「1」について

      1. 枠が、配列binに登録あるかチェック

      2. 登録ないので、bin[1]を作ってデータ値「1」を代入

      3. frequency[1]を作って個数「1」を代入

    2. データ「2」について

      1. 配列binに登録あるか

      2. ないので、bin[2]を作ってデータ値「2」を代入

      3. f[2]を作り個数「1」を代入

    3. データ「4」について

      1. 配列binに登録あるか

      2. ないので、bin[3]を作ってデータ「4」を代入

      3. f[3]を作り「1」を代入

    4. データ「2」について

      1. 配列binに登録あるか

      2. bin[2]=2で既にデータ値入れてるので処理しない

      3. bin[2]にデータ値、個数はf[2]なので個数「+1」する


    図解では色を変えたとはいえ「2」が多いので、もう一度。データを「1, 2, 4, 2」から「1, 2, 4, 4」に変えてみました。

    画像

    ❸にてarray[3]でデータ「4」が来て、
    bin={1, 2}なので「4」の登録なし。
    bin[3]に”[3]がデータ「4」の登録番号だよ”と割り当て、
    frequency[3]に"個数は1個だよ"と初期値。

    ❹にてarray[4]でデータ「4」が来て、
    bin={1, 2, 4}なので「4」がbin[3]に登録あり。[3]に注目。
    frequency[3]に”+1して”、”個数は2個だよ”。




    具体的の構造/パーツを考える

    では擬似言語を作ります。

    前節の手順からポイントをまとめると

    • メインループはデータを読み出すとこ

      • ループカウンタ「i」でarray[i]って読み出す

    データを読み出しながら、以下の処理をします。

    • データ値array[i]が、配列binに登録あるかチェック

      • 前々節のgetIndexInArray関数を使う

    • getIndexInArray関数の返り値が登録なし(-1)なら

      • bin, frequencyに追加。
        「~の末尾に~追加」で初期値を設定。

    • getIndexInArray関数の返り値が登録あり(正値)なら

      • frequency[正値]に+1する。

    全データの読み出し/処理が終了した後に、どれが一番多かったかなと調べて、最頻値を決めます。

    最大値探索には、「整数型: findMaxIndex(整数型の配列: data)」を活用します。
    >【擬似言語⑤】最大値のNote で作成した「findMax関数」を、
    >【擬似言語⑤課題3❶】最頻値 | 方式❶binのNote* で改良。

    findMaxIndex関数から、frequency配列の最大値(=個数が最多)の要素番号が返ってきます。

    bin[要素番号]が、個数が最多のデータ値(=最頻値, モード)ですね。

    では擬似言語を組んでみてください。

    「答え」を待たず、必ずゼロベースで考えてください。私の提示が「答え」とは限りません。自分なりのアルゴ、自分なりの擬似言語を組むのが大事です。その後に、私の提案した答えと比べて下さい。




    答え | データarray[]から最頻値を求める関数

    前節の記述を擬似言語に書きます。かなり具体的に書き出したので、記述通りに組めば完成すると思いますよ。

     
     
    大学・専門学校の先生の解説Note。 学生時代にITパスポート試験・基本情報技術者試験・応用情報技術者試験を独学で高得点合格。情報処理安全確保支援士試験(セキスペ)・データベーススペシャリスト試験・ネットワークスペシャリスト試験・G検定なども取得。 2027年にPD-S受験予定。