2015-11-01 86 views
-1

我需要创建一组0到800之间的随机数。现在的问题是我需要快速执行此操作,并且每个数字只能返回一次。生成随机数字一次

我目前的做法是:

  • 创建包含std::vector从0号到800
  • 选择使用numberVector[rand() % numberVector.length()]
  • 从矢量

我不得不删除这个数目的数目经常这样做,我目前的做法很慢。有什么方法可以在这里加快速度吗?

+0

您是否在搜索例如“生成唯一的随机数”? –

+0

不,我错过了这个词。但是,谢谢!让我进一步! – Nidhoegger

回答

4
  1. 创建含有std::vector的数字从0至800
  2. 洗牌载体中。
    这应该是有用的:c++ - How to shuffle a std::vector? - Stack Overflow
  3. 从头部到尾部逐个取一个向量的元素。您不必删除元素:只存储上次使用的元素的索引。
+0

感谢您的方法!我喜欢!但是,对于速度来说,使用正常数组的这种方法会更好吗? – Nidhoegger

+0

@Nidhoegger:矢量*是引擎盖下面的普通数组。 – Hurkyl

+0

是的,但通过填充800个值,我将有800个分配,对吧?我可以在一个分配中创建一个具有800个值的数组。那是我的想法。但我不知道,我想我会做一个基准:) – Nidhoegger

1
  1. 的std ::洗牌(的std :: random_shuffle)您的std ::矢量
  2. pop_back元素
1

从矢量

你”删除号码可能为此做了太多工作。请记住,例如,从矢量的末尾删除要比从矢量的前面删除要快得多。

既然你不关心其中在你的数字是向量,你可以通过将你想删除的数字移动到向量的末尾来加快速度;例如

int take_from_vector(vector<int> &vec, size_t pos) 
{ 
    int rv = vec[pos]; 
    swap(vec[pos], vec.back()); 
    vec.pop_back(); 
    return rv; 
} 

但是,如果你只是产生了一些东西,它可能是更快地使用拒绝抽样:你跟踪你所生成的数字,然后拒绝任何重复。例如

int generate_another_number(set<int> &already_generated, int bound) 
{ 
    while (true) { 
     int rv = rand() % bound; 
     auto pos = already_generated.insert(rv); 
     if (pos.second) { return rv; } 
    } 
} 

取决于你有多少事情发生,你可能想使用unordered_set<int>,而不是set。或者甚至可以使用vector,只是遍历向量来查看它是否包含生成的数字。


P.S.考虑使用C++的随机数生成功能,而不是古代的rand()函数。