ランダムに全体の配列を繰り返し処理するか、ランダムにいくつかの要素しか必要ないかどうかは教えてください。
最初のケースを想定します。あなたは簿記のための余分なストレージが必要になりますし、とにかくシャッフルのための線形時間が必要になります。それで、順列を作り、あなたが望むようにあなたがそれを再構成できるように、その記憶を生かしてください。
#include <algorithm>
#include <random>
#include <numeric>
struct permutation
{
permutation(size_t n)
: perm(n), g(std::random_device())
{
std::iota(perm.begin(), perm.end(), size_t(0));
}
void shuffle() { std::shuffle(perm.begin(), perm.end(), g); }
size_t operator[](size_t n) const { return perm[n]; }
private:
std::vector<size_t> perm;
std::mt19937 g;
};
使用法:C++ 11で
std::vector<huge_t> v;
...
permutation sigma(v.size());
sigma.shuffle();
const huge_t& x = v[sigma[0]];
...
sigma.shuffle(); // No extra allocation
const huge_t& y = v[sigma[0]];
あなたはC++ 03 std::random_shuffle
を使用するようにコードを適応させるが、乱数生成器に非常に少数の保証があることに注意してくださいすることができます。
あなたのタイプにスワップメソッドを実装できますか?標準ライブラリの実装で、引数に依存するswapの検索が必要な場合は、ベクトルの要素の 'O(1)'スワップを取得します。 –