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

【擬似言語⑪】リーグ戦と文字列比較 | ずらしループと図解(基本情報技術者, 科目B, アルゴリズム)

    このNoteでは、ちょっと複雑なループ制御に挑戦します。今まで「iを1から5まで1ずつ増やす/減らす」程度で固定制御でしたが、開始値/終了値を変数/数式を使って変化させます。

    リーグ戦/移動平均/文字列比較を題材にしたので、実用への生かし方も実感できるように作りました。

    テキストの基礎を生かして、プログラム的な考察/工夫を学んでいきます。基礎と実用にギャップを感じる方のために作りました。
    >【FEB】擬似言語の教科書Note

    ぜひ一緒に学習を進めていきましょう!


    このNoteは、私がIT専門学校で授業したことを基に作成しています。IT専門学校でFEは第一目標として、カリキュラムが構築されています。何も知らずに入学しても、1年生10月にはFE合格していきますよ。実績ある教育ノウハウを詰め込んだので、少しでも信頼して頂けたら嬉しいです。

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


    for文の開始値をズラす | リーグ戦

    今まで「iを1から10まで1ずつ増やす」を基本にしてましたが、「減らす」って制御もできます。>【擬似言語⑩】階乗のNote では、3×2×1を「iを3から1まで1ずつ減らす」で制御しました。

    今回は「jをi+1から」のように、
    i=1のループで、j=2からループ
    i=2のループで、j=3からループ
    jのループ開始値をずらしていく処理をします。

    事例は「4チームのリーグ戦」。
    AvsB, AvsC, AvsD
    BvsC, BvsD
    CvsD
    を表示します

    文字列型の配列: teams ← {"A", "B", "C", "D"}
    整数型: N ← teamsの要素数
    整数型: i, j
    
    for (i を 1 から N - 1 まで 1 ずつ増やす)
      for (j を i + 1 から N まで 1 ずつ増やす)
        teams[i] vs teams[j] を出力する
      endfor
    endfor

    下図を見たら、iとjの開始値/終了値の方針が立ちますね。

    画像

    iを1から3まで。3は「N-1」。
    jを2から4まで。2は「i+1」、4は「N」。
    と分かります。
    jはiが変わるごとに開始値がずれてるので「i」を含んでます。



    for文の開始値をズラす | 移動平均

    移動平均にも使えます。

    「移動平均」はデータを切りだして平均、をずらしていく計算方法。株価でよく使います。滑らかな曲線を得たり、短期~長期の傾向に見るのに便利。

    画像

    簡単なデータを想定して、ループカウンタの計算方法を導きます。>擬似言語の解法11のNote❷

    整数型の配列: data ← {10, 12, 15, 11, 14}
    整数型の配列: result ← {0, 0, 0, 0, 0, 0}
    整数型: N ← dataの要素数
    整数型: i
    
    for (i を 1 から N - 2 まで 1 ずつ増やす)
      result[i] ← (data[i] + data[i + 1] + data[i + 2]) / 3
    endfor

    細かいですが。「result ← {0, 0, 0}」の方が良いですね。計算は3個しかできないので。


    課題も出しますか。今までは3枠の移動平均でしたね。では「2枠の移動平均の擬似言語を作ってください」。下図を参考に調整してみてくださいね。

    画像

    for文内、平均の数式、result配列など見落としないように。一度組んだら、トレースしてみてください。>擬似言語の解法11のNote❺

    今やらなくて良い課題。移動平均する枠数(bin)を引数で受け取って計算するように改良して下さい。Lv.3ぐらいで解説するかも(未定*)




    for文の終了値をズラす | プログレスバー

    次はi, jの二重ループで「jを~から 4-iまで」とし、jのループ終了値をずらしてみます。
    i=1で、j=1~3(=4-1)までループ
    i=2で、j=1~2(=4-2)までループ
    i=3で、j=1~1(=4-3)までループ
    と。jループの回数が減ってます。

    事例は「ローディングの残り時間が減る画面」
    1秒目「***」
    2秒目「**」
    3秒目「*」
    4秒目「ダウンロード終了」
    と表示します。

    整数型: i, j
    
    for (i を 1 から 3 まで 1 ずつ増やす)
      for (j を 1 から 4 - i まで 1 ずつ増やす)
        "*" を出力する(改行なし)
      endfor
      改行を出力する
      1秒待つ
    endfor
    ダウンロード終了 と表示する

    課題。空欄の出力「”  ”を出力する(改行なし)」を使って、
      *
     **
    ***
    を表示してみてください。




    二重ループでのズラし | 文字列比較

    最後にループカウンタを組み合わせた配列の指定もしてみます。

    一発で正解を出そうとしないで下さい。まずは、データと処理を図解に描き出して理解します。数値/数式の発案/調整は後。

    事例は”ある長い文字列”に”ある文字列”が含まれているか、個数を数えます。例えば、文字列「ABCAB」に文字列「AB」が2個含まれているって数える擬似言語。

    画像

    2つの配列text[]とkey[]をどう読み出して比べてるか図示しました。key[]側は「1から2まで1ずつ増やす」ループっぽいですね。

    text[]側はちょっと複雑。iだけじゃなく、jも関わっているって気づいて、さらに調整の「-1」。

    画像

    制御方針が決まったので、擬似言語を組んでみます。

    文字列型の配列: text ← {"A", "B", "C", "A", "B"}
    文字列型の配列: key ← {"A", "B"}
    整数型: i, j, count ← 0
    論理型: match
    
    for (i を 1 から 4 まで 1 ずつ増やす)
      match ← true
      for (j を 1 から 2 まで 1 ずつ増やす)
        if (text[i + j - 1] ≠ key[j])
          match ← false
        endif
      endfor
      if (match)
        count ← count + 1
      endif
    endfor

    さらに汎用性を考えます。textの長さ、keyの長さが違っても動くようにしたいです。for文内の「4まで」「2まで」が固定なのを、textとkeyに応じて自動計算されるように。

    文字列型の配列: text ← {"A", "B", "C", "A", "B"}
    文字列型の配列: key ← {"A", "B"}
    整数型: textLen ← textの要素数
    整数型: keyLen ← keyの要素数
    整数型: i, j, count ← 0
    論理型: match
    
    for (i を 1 から textLen - keyLen + 1 まで 1 ずつ増やす)
      match ← true
      for (j を 1 から keyLen まで 1 ずつ増やす)
        if (text[i + j - 1] ≠ key[j])
          match ← false
        endif
      endfor
      if (match)
        count ← count + 1
      endif
    endfor


    効率化もできるか考えてみます。比べるのを止めて良い場合がありますね。1文字目が違ったら、早々に不一致と判定して終了します。

    画像

    breakを追加します。

    文字列型の配列: text ← {"A", "B", "C", "A", "B"}
    文字列型の配列: key ← {"A", "B"}
    整数型: textLen ← textの要素数
    整数型: keyLen ← keyの要素数
    整数型: i, j, count ← 0
    論理型: match
    
    for (i を 1 から textLen - keyLen + 1 まで 1 ずつ増やす)
      match ← true
      for (j を 1 から keyLen まで 1 ずつ増やす)
        if (text[i + j - 1] ≠ key[j])
          match ← false
          break / 追加したbreak*/
        endif
      endfor
      if (match)
        count ← count + 1
      endif
    endfor

    flagをループ処理前にキメウチして、条件を1回でも満たしたらflagを変更する処理はありましたね。「一度でも割り切れなかったら、素数じゃない、ので以降は素数か判定する必要がないから抜ける」など。
    >擬似言語の教科書Note(⑰反復の離脱)
    >【擬似言語⑧】偶数と素数のNote




    まとめ

    お疲れ様でした!

    図解を描いて、ループカウンターの制御を考える手順が実感できたと思います。かなり難しかったかもですが、これで準備が整いました。

    次回 最終回

    次回は「擬似言語のラスボス」な「バブルソート」を学びます。ループカウンタ(i, j)や配列の基礎や入替アルゴリズムを総動員します。擬似言語と図解の両方の理解が必須の最終課題です。>【擬似言語⑫】バブルソート | 擬似言語のラスボスのNote

    その後も、色んなソートが裏ボスで待っているんですけどね…🫠


    最後に私のお薦めの演習順番。
    ❶学習前の”分からせ”
    >【FEB】サンプル問題2のNote
    ❷テキスト
    >【FEB】擬似言語の教科書Note
    >【FEB】擬似言語の理解演習Note ←いまこの辺
    ↓※必要なら
    うかる! 基本情報技術者 [科目B・セキュリティ編](amazon)
    うかる! 基本情報技術者 [科目B・アルゴリズム編](amazon)
    ❸各年度の公開問題
    >【FEB】令和07年科目BのNote
    >【FEB】令和06年科目BのNote
    >【FEB】令和05年科目BのNote
    ➍解法の総復習(➋や➌と併用可)
    >【FEB】擬似言語の11の解法Note
    ➎模擬試験
    >【FEB】サンプル問題1のNote(擬似言語)
    >【FEB】サンプル問題1のNote(セキュリティ)

    この記事が参加している募集

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