std::random_shuffle, std::shuffle
提供: cppreference.com
ヘッダ <algorithm> で定義
|
||
template< class RandomIt > void random_shuffle( RandomIt first, RandomIt last ); |
(1) | (C++14で非推奨) (C++17で削除) |
(2) | ||
template< class RandomIt, class RandomFunc > void random_shuffle( RandomIt first, RandomIt last, RandomFunc& r ); |
(C++11未満) | |
template< class RandomIt, class RandomFunc > void random_shuffle( RandomIt first, RandomIt last, RandomFunc&& r ); |
(C++11以上) (C++14で非推奨) (C++17で削除) |
|
template< class RandomIt, class URBG > void shuffle( RandomIt first, RandomIt last, URBG&& g ); |
(3) | (C++11以上) |
指定された範囲 [first, last)
の要素を、それらの有り得る順列それぞれが等しい出現率を持つように、並び替えます。
1) 乱数ジェネレータは処理系定義ですが、関数 std::rand がしばしば使用されます。
2) 乱数ジェネレータは関数オブジェクト
r
です。3) 乱数ジェネレータは関数オブジェクト
g
です。目次 |
[編集] 引数
first, last | - | ランダムにシャッフルする要素の範囲 |
r | - | r(n) のように呼ばれた場合に区間 [0,n) 内の std::iterator_traits<RandomIt>::difference_type に変換可能な型のランダムに選択された値を返す関数オブジェクト
|
g | - | 結果の型が std::iterator_traits<RandomIt>::difference_type に変換可能な UniformRandomBitGenerator |
型の要件 | ||
-RandomIt は ValueSwappable および LegacyRandomAccessIterator の要件を満たさなければなりません。
| ||
-std::remove_reference_t<URBG> は UniformRandomBitGenerator の要件を満たさなければなりません。
|
[編集] 戻り値
(なし)
[編集] 計算量
first
と last
の距離に比例。
[編集] ノート
実装は標準によって規定されていないため、まったく同じ RandomFunc
や URBG
を使用したとしても、異なる標準ライブラリ実装では異なる結果が得られる可能性があります。
[編集] 実装例
libstdc++ と libc++ の実装も参照してください。
1つめのバージョン |
---|
template< class RandomIt > void random_shuffle( RandomIt first, RandomIt last ) { typename std::iterator_traits<RandomIt>::difference_type i, n; n = last - first; for (i = n-1; i > 0; --i) { using std::swap; swap(first[i], first[std::rand() % (i+1)]); // rand() % (i+1) isn't actually correct, because the generated number // is not uniformly distributed for most values of i. A correct implementation // will need to essentially reimplement C++11 std::uniform_int_distribution, // which is beyond the scope of this example. } } |
2つめのバージョン |
template<class RandomIt, class RandomFunc> void random_shuffle(RandomIt first, RandomIt last, RandomFunc&& r) { typename std::iterator_traits<RandomIt>::difference_type i, n; n = last - first; for (i = n-1; i > 0; --i) { using std::swap; swap(first[i], first[r(i+1)]); } } |
3つめのバージョン |
template<class RandomIt, class URBG> void shuffle(RandomIt first, RandomIt last, URBG&& g) { typedef typename std::iterator_traits<RandomIt>::difference_type diff_t; typedef std::uniform_int_distribution<diff_t> distr_t; typedef typename distr_t::param_type param_t; distr_t D; diff_t n = last - first; for (diff_t i = n-1; i > 0; --i) { using std::swap; swap(first[i], first[D(g, param_t(0, i))]); } } |
[編集] 例
以下のコードは 1〜10 の整数をランダムにシャッフルします。
Run this code
#include <random> #include <algorithm> #include <iterator> #include <iostream> int main() { std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; std::random_device rd; std::mt19937 g(rd()); std::shuffle(v.begin(), v.end(), g); std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << "\n"; }
出力例:
8 6 10 4 2 3 7 1 9 5
[編集] 関連項目
指定範囲の要素より辞書的に大きな次の順列を生成します (関数テンプレート) | |
指定範囲の要素より辞書的に小さな次の順列を生成します (関数テンプレート) |