I am trying to generate a short range of (about 20) different / unique random numbers.
Here is what I have now:
unique_random.h
:
#ifndef UNIQUE_RANDOM_H
#define UNIQUE_RANDOM_H
// generates a pseudo-random number in [min, max]
int random_number (unsigned int min, unsigned int max) {
static bool seed_initialized = false;
if (!seed_initialized) {
seed_initialized = true;
srand((unsigned int) time(NULL));
}
return rand() % (max - min + 1) + min;
}
// generates a random number different from the previously generated
int random_number_without_these (int min, int max, std::set<int>& generated) {
int res = random_number (min, max);
// if res one of the previous, generate again
while (s.find(res) != s.end()) {
res = random_number (min, max);
}
return res;
}
#endif
then the above functions would be called like so:
main.cpp
:
#include <iostream>
#include <time.h>
#include <set>
#include "unique_random.h"
int main() {
std::set<int> already_generated;
for (auto i = 0; i < 20; ++i) {
int rand = random_number_without_these(1,20, already_generated);
already_generated.insert(rand);
}
}
where the expected result is that there have been generated 20 consecutively unique values. What I have written now needs two functions, random_number_without_these()
, random_number()
and a container, set<int>
, in order to work, that is why I am wondering:
Is there an easier way to generate short range of unique random numbers, possibly along the lines of the existing code?
Using std::set
and e.g. std::uniform_int_distribution
it's actually very easy:
#include <iostream>
#include <set>
#include <random>
std::set<int> generate_numbers(const int min, const int max, const int count)
{
std::set<int> numbers;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(min, max);
while (numbers.size() < count)
{
numbers.insert(dis(gen));
}
return numbers;
}
int main()
{
auto numbers = generate_numbers(1, 20, 20);
for (auto const v : numbers)
{
std::cout << v << ' ';
}
std::cout << '\n';
}
I just don't see the sense in using std::set
since that will keep all the values sorted, and you could just use a simple loop to generate the numbers, or std::iota
. Using std::unordered_set
I can see the point though.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments