C++ でのシャッフルベクター
この記事では、C++ でベクトル要素をシャッフルする方法について複数の方法を示します。
shuffle
アルゴリズムを使用してベクトル要素をシャッフルする
std::shuffle
は C++ の <algorithm>
ライブラリの一部であり、与えられた範囲の要素に適用できるランダムな並べ替え機能を実装しています。この関数は、最初の 2つの引数として範囲イテレータを、3 番目の引数として乱数発生器を受け取ります。乱数発生器は関数オブジェクトです。現代の C++ では、乱数生成の標準ライブラリユーティリティの使用を推奨しています。非決定論的な乱数生成には std::random_device
を利用すべきです。
最後に、選択した乱数エンジンオブジェクトを作成して shuffle
アルゴリズムに渡し、範囲のランダムな順列を生成しなければなりません。シャッフルの前後に整数のベクトルを出力することに注意してください。
#include <algorithm>
#include <iostream>
#include <random>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::shuffle;
using std::string;
using std::vector;
template <typename T>
void printVectorElements(vector<T> &vec) {
for (auto i = 0; i < vec.size(); ++i) {
cout << vec.at(i) << "; ";
}
cout << endl;
}
int main() {
vector<int> i_vec1 = {12, 32, 43, 53, 23, 65, 84};
cout << "i_vec1 : ";
printVectorElements(i_vec1);
std::random_device rd;
std::default_random_engine rng(rd());
shuffle(i_vec1.begin(), i_vec1.end(), rng);
cout << "i_vec1 (shuffled): ";
printVectorElements(i_vec1);
cout << endl;
return EXIT_SUCCESS;
}
出力:
i_vec1 : 12; 32; 43; 53; 23; 65; 84;
i_vec1 (shuffled): 53; 32; 84; 23; 12; 43; 65;
前述のメソッドの代替として、std::begin
と std::end
オブジェクトを用いて同じサブルーチンを実装し、範囲のイテレータを shuffle
関数に渡すこともできます。以下の例は、特定のコーディングシナリオのためのより一般的なバージョンです。
#include <algorithm>
#include <iostream>
#include <random>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::shuffle;
using std::string;
using std::vector;
template <typename T>
void printVectorElements(vector<T> &vec) {
for (auto i = 0; i < vec.size(); ++i) {
cout << vec.at(i) << "; ";
}
cout << endl;
}
int main() {
vector<int> i_vec1 = {12, 32, 43, 53, 23, 65, 84};
cout << "i_vec1 : ";
printVectorElements(i_vec1);
std::random_device rd;
std::default_random_engine rng(rd());
shuffle(std::begin(i_vec1), std::end(i_vec1), rng);
cout << "i_vec1 (shuffled): ";
printVectorElements(i_vec1);
cout << endl;
return EXIT_SUCCESS;
}
出力:
i_vec1 : 12; 32; 43; 53; 23; 65; 84;
i_vec1 (shuffled): 43; 23; 32; 65; 53; 12; 84;
random_shuffle
アルゴリズムを用いてベクトル要素をシャッフルする
std::random_shuffle
は、C++ 標準ライブラリに含まれるもう一つのユーティリティアルゴリズムです。古いバージョンの std::shuffle
は最新の C++ 標準のために減価償却されています。古いバージョンの C++ が利用可能なレガシーなコーディング環境では利用できますが、std::shuffle
を利用することはできません。
random_shuffle
はユーザが提供する乱数発生器を利用することができますが、古いバージョンの C++ ではランダムライブラリの機能が不足していたため、関数に範囲イテレータのみを提供することもあります。後者の場合、random_shuffle
は実装定義の乱数生成器を利用します。
#include <algorithm>
#include <iostream>
#include <random>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::shuffle;
using std::string;
using std::vector;
template <typename T>
void printVectorElements(vector<T> &vec) {
for (auto i = 0; i < vec.size(); ++i) {
cout << vec.at(i) << "; ";
}
cout << endl;
}
int main() {
vector<int> i_vec1 = {12, 32, 43, 53, 23, 65, 84};
cout << "i_vec1 : ";
printVectorElements(i_vec1);
std::random_shuffle(i_vec1.begin(), i_vec1.end());
cout << "i_vec1 (shuffled): ";
printVectorElements(i_vec1);
cout << endl;
return EXIT_SUCCESS;
}
出力:
i_vec1 : 12; 32; 43; 53; 23; 65; 84;
i_vec1 (shuffled): 23; 53; 32; 84; 12; 65; 43;