見出し画像

【擬似言語⑤課題3❷】最頻値 | 方式❷ソート後に数える(基本情報技術者, 科目B, アルゴリズム)

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

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

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

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

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

それでは始めましょう!


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



方式2 | ソート後に数える

今回の方式は、ソートしてから数えます。

”今数えてる値”が変わるまで数えて、変わったら数え直す感じ。

❷がない

下記が、ざっくりした思考の流れ。

  1. 「1だな。数えるぞ。1個。最初だから最頻値にしとこ」

  2. 「2に変わったな。数えるぞ。1, 2個。さっきより多いから最頻値にしとこ」

  3. 「4に変わったな。数えるぞ。1個。さっきより少ないから、関係ないね。」

以上より、最も多いの2個の、2が最頻値。




下準備 | ソート関数を活用するために

要は「bubbleSortOptimizedGlobal()」と引数なしで、配列arrayを並べ替えするようにするってだけです。

「事情」が気になったら、下記を読んでください。


arrayを「大域」で宣言する必要があります。

>【擬似言語⑫】バブルソートのNote にて、「bubbleSortOptimized(整数型の配列: array)」を並べ替えをする関数として作りました。

今回呼び出して結果を受ける必要があります。しかし「配列を返り値にする/複数の返り値を返すのに、コツが要るのがほとんど」です。pythonならできるんですが…。C言語とか大変ですよ…。

FE科目Bでも、配列/複数の値を返り値にするのは避けて「大域」宣言でしています。
>擬似言語の教科書のNote㉚
>【FEB】令和05年科目B問03のNote

sort関数が大域配列dataを操作

今回も、getModeSort関数と呼び出されるbubbleSortOptimized関数で、大域配列arrayを共通して使います。大域宣言は関数外で行うので、bubbleSortOptimized関数の引数でのarray宣言は不要になります。

大域: 実数型の配列: array

○整数型: getModeSort()
  整数型: ~省略~

  // 1. バブルソートで整列させる
  bubbleSortOptimizedGlobal()

○bubbleSortOptimizedGlobal()
  / 配列arrayをバブルソートで並べ替えて上書き */

関数名もbubbleSortOptimizedからbubbleSortOptimizedGlobalに変えました。Globalを追加しただけ。

※違和感を持った方だけお読みください。arrayをいつ入力(引数やファイル読み込み)は割愛させて下さい。別に記載ないmain関数がある感じでお願いします。このNoteはあくまで、アルゴリズムを考えよう/擬似い言語を考えてよう、を主目的にしてます。しっかり書いても、初学者さんが情報過多で混乱しちゃうし、プログラム言語によってまた色々アレンジ必要ですもんね。




関数の仕様

では、手順を具体的に擬似言語に書き出す準備をします。

❷がない

❶ソートは「bubbleSortOptimizedGlobal()」を呼び出すだけでOK。

❷現在数えている値を変数「currentVal」に、個数を「currentCount」に記録。最頻値は「modeVal」に、個数を「modeCount」に記録。


数えている値が変わったら、今まで数えていた値(currentVal)の個数(currentCount)が、暫定最頻値(modeVal)の個数(modeCount)より大きいか審査。
大きければ、暫定最頻値と個数を更新して新王者に。大きくなければ王者ならず(何もしない)。

重要なイベントは、数える値の変化。

数えている値が変わったら、数える値(currentVal)をこれから数える値に変更、個数(currentCount)はにリセット(0か1かは要検討。アルゴリズムに依るので。)。

でも1番目の値は「値が変わったら」は起きない。数える系(currentVal, currentCount)と暫定最頻値系(modeVal, modeCount)の初期化で対応かな。図の「初代」王者。

以上。言葉で書きましたが、チンプンカンプンだったら、実力か考えが足りてないです。手順を理解して自分で組みに挑戦できるぐらいなら、文章で「ふんふんそうだね」と、割と共感できるはず。




答え | ループカウンタを「1」開始

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

まずは処理のブロックを作って、ループや分岐条件を立てて、簡単なデータでトレースして動作確認する流れ。

ブロックは下記。

  • 数える値が変わってない時の数え上げ(count←count+1的な)

  • 数える値が変わった時の処理

    • 今まで数えた値を最頻値にするか/しないか

    • これから数えるための準備(変数のリセット)

  • 上記をループに組み込む

  • 1番目のデータはループ開始前orループ内で処理するか考える

今回はループカウンタを「1」から始めたいので、1番目のデータ処理もループ内で行なってもツジツマが合うような初期値を、ループ前に行います(currentCount←0)。

ここから先は

2,831字

メンバーシップ ¥ 500 /月

■初月無料なので、お試しください。 ■私独自の理解法や詳しい分析を公開したいです。 ■根本を丁寧に見…

【初月無料】Iパス法律/SG/AP計算/DBとSC午後2

¥500 / 月
1ヶ月無料 人数制限あり

学習方法・問題特集のNoteは全て無料提供を続けます▼ もしご覧になったNoteが有益だったり、私の志に共感されたりしましたら、サポート頂けますと励みになります▼ もちろんコメントでも結構です(・ω・▼)ノシ