から非反復ランダム数のセットを生成したいと思い0...n
ます。
例:[9,2,5,7,4,6,1,3,8,0]
std::set
私の現在の方法は、カウントがになるまでwhileループで乱数を生成することですn
。明らかに、これは大きなセットで終了するのにかなりの時間がかかります。これを行うためのより良い方法はありますか?
順次値をSTLコレクションに配置してから、 random_shuffleを使用してそれらを適切にシャッフルできます。
番号のリストをシャッフルして繰り返します。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> v;
for(int i=0;i<10;i++)
v.push_back(i);
random_shuffle(v.begin(), v.end());
for(vector<int>::iterator itr=v.begin(); itr != v.end(); ++itr)
cout << *itr << endl;
}
シーケンスの生成とシャッフルは必要な場合がありますが、必ずしも乱数を生成して以前に発生したものを破棄することと同じではありません。たとえば、100万から200万の間の10個の一意のランダムな数値が必要な場合、生成するだけでは明らかに目的の分布が得られません。
1,000,000
1,000,001
1,000,002
1,000,003
1,000,004
1,000,005
1,000,006
1,000,007
1,000,008
1,000,009
そしてそれらをシャッフルします。
代わりに、希望する数になるまで希望の範囲からランダムな数字を生成し、結果を並べ替えて一意にし、一意化によって削除されたものを補うのに十分な追加のランダムな数字を生成することができます(新しい数字が一意になるようにします) )。生成される数値の範囲が必要な値の数よりもそれほど大きくない場合は、最初にいくつかの追加の値を生成するだけで済みます。いずれにせよ、必要な数の一意の値を取得したら、それらがソートされた順序にならないようにシャッフルすることが最後のステップです。
試してみてください。
#include <iostream>
#include <algorithm>
using namespace std;
void main()
{
int *tab;
int nr;
srand(time(0));
cout << "How many numbers do you want to generate?: ";
cin >> nr;
tab = new int[nr]; //Dynamic memory allocation
for (int i = 0;i < nr;i++)
tab[i] = i+1;
random_shuffle(&tab[0], &tab[nr]); //Shuffle the numbers from tab;
cout << "\t\tMixed numbers are: " << endl;
for (int i = 0;i < nr;i++)
cout << "Number [" << i + 1 << "]: " << tab[i]<<endl;
delete [] tab;
cin.get();