我正在尝试用随机序列中1-20的数字填充20个整数的数组。 这是我的代码:
int lookup[20]={0};
int array[20]={0};
srand(time(NULL));
for(int i=0;i<20;++i){
bool done=false;
while(!done){
int n=rand()%20;
if(lookup[n]==0){
array[i]=n;
lookup[n]=1;
done=true;
}
}
}
我创建了一个查找数组来检查是否尚未选择随机数并将其存储在数组中。正如你所看到的,我创建了2个循环,一个用于遍历数组,而while用于选择随机数。在每次循环迭代中,数字可能会重新出现并导致另一个while循环。有更快的方法吗?
答案 0 :(得分:19)
您可以按顺序填充数组,然后将其随机播放。这样可以防止不得不进行超过20次随机数生成。
Fisher-Yates shuffle:可以在O(n)时间内完成。
来自维基百科:
正确实施,Fisher-Yates shuffle是公正的,因此每个排列都是同样可能的。该算法的现代版本也相当高效,只需要与被洗牌的项目数量成比例的时间,而不需要额外的存储空间。
答案 1 :(得分:15)
答案 2 :(得分:9)
您可以使用1到20之间的数字填充数组并使用std::random_shuffle
请注意,简单数组不需要矢量。
例如:
#include <iostream>
#include <algorithm>
using namespace std;
int main( void )
{
int array[] = { 0, 1, 2, 3, 4 };
srand( unsigned( time(NULL) ) );
random_shuffle(array, array+5);
for(int i=0; i<5; i++)
cout << array[i] << endl;
return 0;
}
答案 3 :(得分:1)
你的代码中有可能存在一个很长的循环循环。如果你在while(!done)循环中,那么你无法保证完成。显然,对于20个元素的数组,这实际上不是一个问题,但如果你将它扩展到数千个元素,它可能会导致问题。
更可靠的解决方案是按顺序填充数组,然后再将其洗后。
答案 4 :(得分:0)
我将20个随机数放在一个数组中,然后复制到另一个20个元素数组,对一个数组进行排序,对于排序数组中的每个数字,找到未排序数组中的相应数字,并将索引放入那里那种。
答案 5 :(得分:0)
如果你可以使用容器,我只需用1到20的数字填充std :: set。
然后你可以从你的集合中提取一个随机数并将其插入到数组中。
答案 6 :(得分:0)
这样的事情?
int n = 20; //total element of array
int random = 0, temp=0, start=1;
for(int i=0; i < n; ++i,++start)
{
array[i] = start;
}
for(int i=0; i<n ; ++i)
{
random=rand()%(n-i)+i;
//swapping, you can make it as a function
temp = array[i];
array[i] = array [random];
array[random] = temp;
}
答案 7 :(得分:0)
其他可能的方式
int array[20]={0};
int values[20];
for(int i = 0; i < 20; i++)
values[i] = i;
int left = 20;
for(int i = 0; i < 20; i++)
{
int n = rand() % left;
array[i] = values[n];
left--;
values[n] = values[left];
}
PS填充0到19之间的数字而不是1到20.与原始相同
答案 8 :(得分:0)
Fisher-Yates的代码示例:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void shuffle(int array[], size_t size)
{
if(size) while(--size)
{
size_t current = (size_t)(rand() / (1.0 + RAND_MAX) * (size + 1));
int tmp = array[current];
array[current] = array[size];
array[size] = tmp;
}
}
int main(void)
{
srand((int)time(NULL));
rand(); // throw away first value: necessary for some implementations
int array[] = { 1, 2, 3, 4, 5 };
shuffle(array, sizeof array / sizeof *array);
size_t i = 0;
for(; i < sizeof array / sizeof *array; ++i)
printf("%i\n", array[i]);
return 0;
}
答案 9 :(得分:0)
我希望它会有所帮助:
std::generate(array, array + sizeof(array)/sizeof(int), ::rand);
下面是完整的代码:
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<iterator>
int main()
{
int array[] = {1, 2, 3, 4};
const unsigned SIZE = sizeof(array)/sizeof(int);
cout << "Array before: ";
std::copy(array, array+SIZE, std::ostream_iterator<int>(cout, ", "));
std::generate(array, array+SIZE, ::rand); // answer for your question
cout << "\nArray arter: ";
std::copy(array, array+SIZE, std::ostream_iterator<int>(cout, ", "));
}
如果您希望产生的数字小于生成后的数字:
std::transform(array, array+SIZE, array, std::bind2nd(std::modulus<int>(), 255));