C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++のshuffleとrandom_shuffleの使い方と違いを解説

この記事では、C++のshuffle関数とrandom_shuffle関数について詳しく解説します。まずはrandom_shuffleから見ていきましょう。

random_shuffle()は、範囲[left, right)内の要素をランダムに並べ替えるための関数です。各要素の位置を、ランダムに選ばれた別の位置と入れ替えることでシャッフルを実現します。

独自の乱数生成関数を渡すことで、どの要素を選ぶかの挙動をカスタマイズすることも可能です。乱数生成関数を指定しない場合は、関数内部に組み込まれたデフォルトの乱数生成機構が使用されます。

random_shuffle()のサンプルコード

#include <bits/stdc++.h>
using namespace std;
int myRandomGenerator(int j) {
    return rand() % j;
}
main() {
    srand(unsigned(time(0)));
    vector<int> arr;
    for (int j = 1; j < 20; ++j) // 1〜19の数値を生成してvector arrに追加
        arr.push_back(j);
    random_shuffle(arr.begin(), arr.end()); // 組み込みの乱数機能でシャッフル
    cout << "arr elements:";
    for (vector<int>::iterator i = arr.begin(); i != arr.end(); ++i)
        cout << ' ' << *i;
    cout << endl;
    // myRandomGeneratorを使用
    random_shuffle(arr.begin(), arr.end(), myRandomGenerator);
    cout << "arr elements:";
    for (vector<int>::iterator i = arr.begin(); i != arr.end(); ++i)
        cout << ' ' << *i;
    cout << endl;
}

実行結果

arr elements: 5 14 15 6 3 16 13 12 10 2 4 1 17 9 18 11 7 8 19
arr elements: 8 10 5 6 14 1 15 3 19 16 13 18 7 9 4 12 11 17 2

shuffle()の使い方

次にshuffle()関数について見ていきましょう。この関数も範囲[left, right)内の要素をランダムに並べ替えるために使用されますが、一様乱数生成器(uniform random number generator)を引数として受け取る点が大きな特徴です。

shuffle()のサンプルコード

#include <bits/stdc++.h>
using namespace std;
main() {
    vector<int> arr;
    unsigned seed = 0;
    for (int j = 1; j < 20; ++j) // 1〜19の数値を生成してvector arrに追加
        arr.push_back(j);
    shuffle(arr.begin(), arr.end(), default_random_engine(seed));
    cout << "arr elements:";
    for (vector<int>::iterator i = arr.begin(); i != arr.end(); ++i)
        cout << ' ' << *i;
    cout << endl;
}

実行結果

arr elements: 19 7 5 6 12 4 13 3 1 17 11 14 18 2 8 15 9 10 16

random_shuffle()とshuffle()の違い

両者の違いは、random_shuffle()がrand()関数を用いてランダムなインデックスを生成するのに対し、shuffle()は一様乱数生成器を使用する点にあります。ただし、random_shuffle()に一様乱数生成器を渡した場合は、同様の結果を得ることができます。

なお、random_shuffle()はC++14で非推奨(deprecated)となり、C++17では標準ライブラリから削除されました。現在のC++では、一様乱数生成器を引数に取るshuffle()の使用が推奨されています。新規のコードを書く際は、shuffle()を選ぶようにしましょう。


  1. C++でプロセスを強制終了する方法:BFSを使った実装解説

    n個のプロセスがあると仮定します。各プロセスには、PID(プロセスID)と呼ばれる一意の識別子が割り当てられており、さらにPPID(親プロセスID)も持っています。各プロセスが持てる親プロセスは1つだけですが、子プロセスは1つでも複数でも構いません。これはまさに木構造と同じ形です。PPIDが0になるプロセスは1つだけであり、それはそのプロセスに親が存在しないことを意味します。また、すべてのPIDは一意な正の整数です。問題の概要ここでは、2つの整数リストを使ってプロセスの一覧を表現します。1つ目のリストには各プロセスのPIDが含まれ、2つ目のリストにはそれに対応するPPIDが含まれます。このとき

  2. C++で解くリスのナッツ収集シミュレーション ― 最小移動距離を求めるアルゴリズム

    問題概要 1本の木、1匹のリス、そして複数のナッツがフィールド上にあります。それぞれの位置は2次元グリッドのセルで表現されます。この問題の目的は、リスがすべてのナッツを集めて木の下に1個ずつ運ぶときの最小移動距離を求めることです。 リスの行動には次の制約があります。 一度に持てるナッツは最大1個 移動は上下左右の4方向で、隣接するセルへのみ可能 距離は移動回数(ステップ数)で表される たとえば、入力が「高さ: 5 / 幅: 7 / 木の位置: [2,2] / リスの位置: [4,4] / ナッツ: [[3,0], [2,5]]」の場合、出力は 12 となります。 解法のポイント まず、