0Pricing
C++ Academy · レッスン

実践例

サイコロ、シャッフル、サンプリング

「実践例」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。

サイコロを振る

6面体のサイコロは、シードを設定したエンジンから値を受け取るuniform_int_distribution(1, 6)で表せます。

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(2026);
    std::uniform_int_distribution<int> die(1, 6);
    for (int i = 0; i < 5; ++i) std::cout << die(gen) << ' ';
    std::cout << '\n';
    return 0;
}

2個のサイコロの合計

2個のサイコロを振って合計すると、7が最頻値となる、おなじみの2から12までの範囲になります。

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(1);
    std::uniform_int_distribution<int> die(1, 6);
    int total = die(gen) + die(gen);
    std::cout << "two dice sum: " << total << '\n';
    return 0;
}

コインを投げる

公平なコインはbernoulli_distribution(0.5)で表せます。何度も投げて表が出た回数を数えます。

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(7);
    std::bernoulli_distribution coin(0.5);
    int heads = 0;
    for (int i = 0; i < 100; ++i) if (coin(gen)) ++heads;
    std::cout << heads << " heads out of 100\n";
    return 0;
}

デッキをシャッフルする

std::shuffleはエンジンを使って範囲をランダムに並べ替えます。削除されたrandom_shuffleに代わる、現代的な機能です。

#include <iostream>
#include <random>
#include <algorithm>
#include <vector>

int main() {
    std::vector<int> cards{1, 2, 3, 4, 5};
    std::mt19937 gen(3);
    std::shuffle(cards.begin(), cards.end(), gen);
    for (int c : cards) std::cout << c << ' ';
    std::cout << '\n';
    return 0;
}

ランダムな勝者を選ぶ

範囲内のランダムなインデックスを生成して、要素を1つ選択します。

#include <iostream>
#include <random>
#include <vector>
#include <string>

int main() {
    std::vector<std::string> names{"Ann", "Ben", "Cara", "Dan"};
    std::mt19937 gen(9);
    std::uniform_int_distribution<int> pick(0, names.size() - 1);
    std::cout << "winner: " << names[pick(gen)] << '\n';
    return 0;
}

復元抽出なしのサンプリング

std::sampleは範囲から異なるk個の要素を取り出します。抽選やクイズの出題対象の選択に最適です。

#include <iostream>
#include <random>
#include <algorithm>
#include <vector>

int main() {
    std::vector<int> pool{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    std::vector<int> picked;
    std::mt19937 gen(4);
    std::sample(pool.begin(), pool.end(), std::back_inserter(picked), 3, gen);
    for (int x : picked) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

ランダムなパスワード文字

一様分布を使って文字セットのインデックスを選び、ランダムな文字列を作成します。

#include <iostream>
#include <random>
#include <string>

int main() {
    const std::string chars = "abcdefghijklmnopqrstuvwxyz";
    std::mt19937 gen(13);
    std::uniform_int_distribution<int> pick(0, chars.size() - 1);
    std::string pw;
    for (int i = 0; i < 8; ++i) pw += chars[pick(gen)];
    std::cout << pw << '\n';
    return 0;
}

重み付き選択

std::discrete_distributionは指定された重みに従ってインデックスを選ぶため、確率の高い結果ほど頻繁に現れます。

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(6);
    std::discrete_distribution<int> d{10, 1, 1}; // index 0 is heaviest
    int counts[3] = {0};
    for (int i = 0; i < 120; ++i) counts[d(gen)]++;
    std::cout << counts[0] << ' ' << counts[1] << ' ' << counts[2] << '\n';
    return 0;
}

ランダムウォークのシミュレーション

左または右へランダムに進み、最終位置を記録します。これは単純な確率過程のシミュレーションです。

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(2);
    std::bernoulli_distribution step(0.5);
    int pos = 0;
    for (int i = 0; i < 1000; ++i) pos += step(gen) ? 1 : -1;
    std::cout << "final position: " << pos << '\n';
    return 0;
}

6が出るまでサイコロを振る

ある事象が起こるまでループして試行をモデル化します。ここでは、6が出るまでに必要な試行回数を数えます。

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(15);
    std::uniform_int_distribution<int> die(1, 6);
    int rolls = 0;
    while (die(gen) != 6) ++rolls;
    std::cout << "extra rolls before a six: " << rolls << '\n';
    return 0;
}

テストデータの生成

分布を使うと、アルゴリズムのテスト用にランダムな値をvectorへすばやく格納できます。

#include <iostream>
#include <random>
#include <vector>

int main() {
    std::mt19937 gen(21);
    std::uniform_int_distribution<int> d(1, 50);
    std::vector<int> data(5);
    for (int& v : data) v = d(gen);
    for (int v : data) std::cout << v << ' ';
    std::cout << '\n';
    return 0;
}

理解度チェック

実践的な乱数の扱いについての理解度を確認します。

まとめ

<random>を実際に使用しました。

  • 一様分布とbernoulli分布を使ったサイコロ、コイン、勝者の選択
  • std::shuffleによる並べ替えと、std::sampleによる復元抽出なしのサンプリング
  • 重み付き選択のためのdiscrete_distributionと、ランダムウォークなどのシミュレーション

これで、C++における連想コンテナー、ハッシュ、ファイル入出力、乱数を扱うためのツールキットが揃いました。

よくある質問

「実践例」レッスンは無料ですか?

はい。「実践例」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。

「実践例」で何を学びますか?

サイコロ、シャッフル、サンプリング ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C++ Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「実践例」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC++ Academyレッスンでコードを書いて実行できますか?

はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 乱数エンジン
  2. 分布
  3. 適切なシード設定
  4. 実践例
← C++ Academyに戻る