我想从0到39生成7个随机数,并将它们存储在一维数组中。我必须确保每个数字都不同(例如不能有两个7)。
我考虑过改组数字,但是我只需要40个中的7个。实际上我必须在学校做这个,我们还没有涉及到指针,我们正在使用rand()函数来获取随机数。我猜想解决方案并不一定要是真正随机的,至少要有一定的可能性。
答案 0 :(得分:3)
好的,这是我的贡献:
#include <iostream>
#include <algorithm>
#include <random>
#include <vector>
int main()
{
std::vector <int> v (40);
std::generate (v.begin (), v.end (), [n = 0] () mutable { return n++; });
std::random_device rd;
std::mt19937 g (rd ());
std::shuffle (v.begin (), v.end (), g);
for (int i = 0; i < 7; ++i)
std::cout << v [i] << '\n';
}
代表输出:
5
39
10
17
36
11
31
编辑:如skeller所述,对std::generate
的呼叫可以替换为:
std::iota (v.begin (), v.end (), 0);
整洁很多。
如果愿意,也可以将std::vector v (40);
替换为std::array <int, 40> v;
。
答案 1 :(得分:0)
有人在评论中指出,教导现代随机方法很重要。所以这是我的看法:
现代C ++方法
#include <iostream>
#include <algorithm>
#include <vector>
#include <numeric>
#include <random>
using namespace std;
int main()
{
std::vector<int> AllValues(40) ; // Vector of 40 integers
std::iota (std::begin(AllValues), std::end(AllValues), 0); // Fill AllValues with 0..39
std::random_device RandomDevice; // Create a random device
std::default_random_engine RandomEngine(RandomDevice()); // Create a random engine, seeding from RandomDevice
std::shuffle(std::begin(AllValues), std::end(AllValues), RandomEngine); // Shuffle AllValues using RandomEngine
std::vector<int> RandomNumbers(AllValues.begin(), AllValues.begin() + 7); // Create a new vector using the first 7 numbers of AllValues
// Display the 7 random values
for (auto i: RandomNumbers)
std::cout << i << std::endl;
return 0;
}
话虽这么说,但如果我能得到您的共鸣,您将更希望学习它的完成方式,而不是“正确而现代的”答案。
让我们看看您要问的参数。
您需要在一个数组中生成7个随机数,确保没有一个值出现两次。由于选择两次相同的随机数的几率很低(第7个数字为6/40 [15%]),因此我将使用两个循环来进行选择。这将始终有效,并且无需打高尔夫球就能占用最少的内存。
#include <iostream>
#include <random>
using namespace std;
// Those defines could be constants
#define NB_RANDOM_NUMBERS (7)
#define RAND_MODULO (40)
int main()
{
std::random_device seeder; // Obtain a seed for the random number engine
std::mt19937 generator(seeder()); // mersenne_twister_engine seeded with seeder()
std::uniform_int_distribution<> randomizer(0, RAND_MODULO-1);
int RandomNumbers[NB_RANDOM_NUMBERS]; // the array that'll get the random numbers
// A loop for all seven random numbers
for(int numberIndex = 0; numberIndex < NB_RANDOM_NUMBERS; numberIndex++)
{
bool found; // indicates if we found the new number in a previous iteration
do
{
// Generate a new random number
RandomNumbers[numberIndex] = randomizer(generator);
/*
*** If using rand() is required : ***
RandomNumbers[numberIndex] = rand() % RAND_MODULO;
*/
// Check if it was found or not in a previous iteration
found = false;
for(int checkNumber = 0; checkNumber < numberIndex && !found; checkNumber++)
{
// Is the new number already in the array?
if(RandomNumbers[checkNumber] == RandomNumbers[numberIndex])
{
// Exit the loop and restart over
found = true;
}
}
}
while(found);
cout << numberIndex+1 << " : " << RandomNumbers[numberIndex] << std::endl;
}
return 0;
}
请注意,NB_RANDOM_NUMBERS-1
越接近RAND_MODULO
,该算法将运行的时间越长。例如,如果要从100个池中生成90个随机数,则最后一个随机数将有89%的机会已经在RandomNumbers
数组中。内部循环可能会运行很长时间,并且算法效率不高。
在这种情况下,填充所有值的数组并随机选择它们会更有效:
#include <iostream>
#include <random>
using namespace std;
#define NB_RANDOM_NUMBERS (7)
#define RAND_MODULO (40)
int main()
{
std::random_device seeder; // Obtain a seed for the random number engine
std::mt19937 generator(seeder()); // mersenne_twister_engine seeded with seeder()
std::uniform_int_distribution<> randomizer(0, RAND_MODULO-1);
int RandomNumbers[NB_RANDOM_NUMBERS]; // the array that'll get the random numbers
int AllValues[RAND_MODULO]; // a array of all numeric values to chose from
for(int i = 0; i < RAND_MODULO; i++)
{
AllValues[i] = i;
}
// A loop for all seven random numbers
for(int numberIndex = 0; numberIndex < NB_RANDOM_NUMBERS; numberIndex++)
{
int randomIndex;
// Search for a random index that doesn't contain -1
do
{
randomIndex = randomizer(generator);
}
while(AllValues[randomIndex] == -1);
// Assign the number at the random index you generated
RandomNumbers[numberIndex] = AllValues[randomIndex];
// Set it to -1 in preparation of the next iteration
AllValues[randomIndex] = -1;
cout << numberIndex+1 << " : " << RandomNumbers[numberIndex] << std::endl;
}
return 0;
}
答案 2 :(得分:0)
我的相同算法的C ++版本。
#include <iostream>
#include <algorithm>
#include <random>
#include <vector>
using namespace std;
int main()
{
std::random_device rd;
std::mt19937 g (rd ());
std::vector <int> v(40);
std::iota(v.begin(), v.end(), 0); // Fill the vector with values 0-39
std::vector<int> output(7);
std::generate(output.begin(), output.end(),
[v,g]()mutable
{
auto pos = v.begin() + (g()%v.size()); // Pick an element at random (by iterator)
int value = *pos; // Get the value of random element
iter_swap(pos, v.begin() + v.size() - 1); // Swap the random element to the end of vector
v.pop_back(); // Erase the last element of vector (the random element)
return value; // Return the randomly chosen value
});
for (auto& x : output) std::cout << x << '\n';
return 0;
}
答案 3 :(得分:-1)
这是通过从数组中选择随机元素,然后缩短数组以删除所选元素来实现的。
内嵌评论和解释:
#include <stdio.h>
int main(void) {
int array[40];
for(int i=0;i<40; ++i) array[i]=i; // Fill an array 0-39, in order.
int output[7];
for(int i=0; i<7; ++i)
{
int rnd_index = rand()%(40-i); // Pick a random index in the array.
output[i] = array[rnd_index]; // Copy randomly selected value to the output array
array[rnd_index] = array[40-i-1]; // Copy the last item in the array to the randomly selected item, effectively removing the selected item from the pool
}
// Show the output
for(int i=0; i<7; ++i) printf("[%d] : %d\n", i, output[i]);
return 0;
}
Success #stdin #stdout 0s 9424KB
[0] : 23
[1] : 22
[2] : 3
[3] : 9
[4] : 5
[5] : 10
[6] : 20
请注意,在使用rand()和取模运算时会有轻微的选择偏差。 如果您需要更完美的平面分布,则需要改进。