std::random_shuffle(b,e)
実装で定義されたランダム性のソースを使用するため、これを移植可能に制御することはできません。通常、実装は rng をシードするstd::rand()
ために使用するため、多くの場合機能します。std::srand()
// not portable, depends on implementation defined source of randomness in random_shuffle
std::srand(some_seed);
std::random_shuffle(answerPositionArray, answerPositionArray+size);
std::random_shuffle()
3 番目のパラメーターとして乱数ジェネレーターを取るオーバーロードがあります。このフォームを使用してランダム性のソースを定義し、それをシードすることができます。
struct RNG {
int operator() (int n) {
return std::rand() / (1.0 + RAND_MAX) * n;
}
};
std::srand(seed);
std::random_shuffle(answerPositionArray, answerPositionArray+size, RNG());
std::shuffle
C++11では、UniformRandomNumberGenerator を取る別のアルゴリズムが導入され、C++11<random>
ジェネレーターを使用できるようになります。
std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 eng(seed);
std::shuffle(std::begin(answerPositionArray), std::end(answerPositionArray), eng);
あなたのコメントは、配列全体をシャッフルしていないこと、最初の2つの要素のみをシャッフルしていて、最後の要素に触れていないことが問題であることを示しています。
これは、コードのようにマジック ナンバーを使用する方法の良いデモンストレーションです。
std::random_shuffle(answerPositionArray, answerPositionArray + 2);
^
|
magic number --
エラーが発生しやすい可能性があります。代わりに、そのような値とは無関係に機能するコードを書くようにしてください。
// trick for getting an array size
template<typename T, int N> int array_size(T (&)[N]) { return N; }
int answerPositionArray[] = {100, 400, 800};
std::random_shuffle(answerPositionArray,
answerPositionArray + array_size(answerPositionArray));
または、C++11 を使用できるようになったら、配列に対してstd::begin
andを使用できます。std::end
std::random_shuffle(std::begin(answerPositionArray), std::end(answerPositionArray));
または、上記の配列サイズのトリックを使用して、C++03 で自分で実装begin
して機能させることもできます。end
template<typename T, int N> T *begin(T (&a)[N]) { return a; }
template<typename T, int N> T *end(T (&a)[N]) { return a + N; }
これらのメソッドを使用すると、配列サイズにマジック ナンバーを使用する必要がなくなるため、コードを記述または変更するときに、間違った値を誤って使用する可能性が低くなります。