在 cmets 中指出,教授现代随机方法很重要。所以这是我的看法:
现代 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;
}