Generate random letters - c++

string bolsa_letras::letters_generator(int quantity){
int already_generated = 0;
map<char, int> aux = values;
string out;
while(already_generated != quantity){
char generated_char = 'A' + rand()%26;
if(aux[generated_char] > 0){
out.push_back(generated_char);
aux[generated_char]--;
already_generated++;
}
}
return out;
}
Above is the code that given a number generates random letters.
The map saves the letters and the times that letters can be appeared. The problem is that every time i run the code, it prints the same: NLRBBMQH. Why is so?
I have include cstdlib for the rand function.

A deterministic program cannot naturally generate randomness. We need to get that randomness from elsewhere. In the old days of rand(), we'd generally seed the RNG with the result of std::time(NULL) to produce a different state at each run.
Nowadays, we use the tools provided by <random> which are "more random".
From cppreference.com's documentation on std::uniform_int_distribution you can find an example for integers of type int. Now, char is an integer type too. Let us tweak their example a tiny bit:
#include <random>
#include <iostream>
int main()
{
std::random_device rd; // Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<char> dis('A', 'Z');
for (int n=0; n<10; ++n) {
std::cout << dis(gen) << ' ';
}
std::cout << '\n';
}
And tadaaaa! a random letter generator :)
Live demo

Related

Math.Random equivalent in C++

I have been programming in Java for three years, and have been using Math.random() to get a random number. I'm fairly new to C++, and I was wondering if there was equivalent to that but in C++? A specific function or method that I could use? Also include an explanation. Thanks so much!
C++ provides a fairly nice random number library, <random>, but it doesn't yet have the sort of dead simple API beginners generally want. It's easy to produce such an API, as I show below, and hopefully some such API will be included at some point.
The C++ API splits random number generation into two parts, sources of 'randomness', and machinery for turning randomness into numbers with specific distributions. Many basic uses of random numbers don't particularly care how good (or fast, or small) the source of 'randomness' is, and they only need 'uniform' distributions. So the typically recommended source of randomness is the "Mersenne Twister" engine. You create one of these and seed it like so:
#include <random>
int main() {
std::mt19937 eng{42};
}
Now eng is an object that can be passed around and used as a source for random bits. It's a value-type so you can make copies of it, assign to it, etc. like a normal value. In terms of thread safety, accessing this value is like accessing any other, so if you need multiple threads you should either put an engine on each thread or use mutual exclusion.
To turn data from an engine into random values, use a distribution object. Typical uses need 'uniform' distributions, so for integral values use std::uniform_int_distribution<int>.
std::uniform_int_distribution<int> dice{1, 6};
A distribution object is a function object, and you get values from it by calling it and passing it the source of randomness it will use:
auto die_roll = dice(eng);
One thing to keep in mind is that the math for producing random values should be encapsulated inside a distribution object. If you find yourself doing some kind of transformation on the results then you probably should be using a different distribution. Don't do things like dist(eng) % 10 or dist(eng) / 6.0 + 10.0. There are several other distributions provided in the library, including ones for producing floating point values with various distributions.
Here's a pretty easy way to wrap the <random> functionality for simple usage:
#include <iostream>
#include <random>
std::mt19937 seeded_eng() {
std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
return std::mt19937(seed);
}
class Random {
std::mt19937 eng = seeded_eng();
public:
auto operator()(int a, int b) {
std::uniform_int_distribution<int> dist(a, b);
return dist(eng);
}
};
int main() {
Random random;
for (int i = 0; i < 10; ++i) {
std::cout << "Dice: " << random(1, 6) << " " << random(1, 6) << '\n';
}
}
#include <iostream>
#include <ctime>
int main()
{
srand((unsigned int) time (NULL)); //activates the generator
//...
int a = rand()%10; //gives a random from 0 to 9
double r = ((double) rand() / (RAND_MAX)); //gives a random from 0 to 1
int max, min;
//...
int c = (rand()%(max - min)) + min; //gives a random from min to max
//...
return 0;
}
These ways are the simpliest.
Sometimes it means "the best", sometimes - not.
1.srand((unsigned) time(0)) will make sure that everytime you run your program that the rand() function will get a new seed causing it to produce a different or "random" output. Without stand((unsigned) time(0)), the rand() will produce the same output.
2.int Number, is used to store the random number that is being generated by the rand() function. The rand() % 27 will give you numbers 0-26.
#include <iostream>
#include <ctime>
int main()
{
srand((unsigned)time(0))
int Number = ((rand() % 27));
cout << Number << endl;
return 0;
}
Here is a simple solution. The function random is overloaded. One instance is used to acquire a random number generator for integers. Another instance is used to acquire a random number generator for doubles. After you have these two functions, applications becomes rather trivial as can be observed in the main function.
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <numeric>
#include <ostream>
#include <random>
// Single global engine, a better version of std::rand
std::mt19937 engine{ std::random_device()() };
// Returns a generator producing uniform random integers in the closed range [a, b]
std::function<int()> random(int a, int b)
{
auto dist = std::uniform_int_distribution<>(a, b);
return std::bind(dist, std::ref(engine));
}
// Returns a generator producing uniform random doubles in the half-open range [x, y)
std::function<double()> random(double x, double y)
{
auto dist = std::uniform_real_distribution<>(x, y);
return std::bind(dist, std::ref(engine));
}
int main()
{
const auto no_iterations = int{ 12 };
auto dice = random(1, 6);
// Roll the dice a few times and observe the outcome
std::generate_n(std::ostream_iterator<int>(std::cout, " "),
no_iterations, dice);
std::cout << std::endl;
// U is a uniform random variable on the unit interval [0, 1]
auto U = random(0.0, 1.0);
// Generate some observations
std::vector<double> observations;
std::generate_n(std::back_inserter(observations), no_iterations, U);
// Calculate the mean of the observations
auto sum = std::accumulate(observations.cbegin(), observations.cend(), 0.0);
auto mean = sum / no_iterations;
std::cout << "The mean is " << mean << std::endl;
return 0;
}

Elegant way to draw n random values in C++11?

For my program, I needed so far to draw one random value in [0..k[ from time to time, and using C++11 <random> features works really well. My current code is something like
class Random
{
public:
Random() : rng( rd() ) { }
inline int getRandNum( int limit ) { return ( numbers(rng) % limit ); }
private:
std::random_device rd;
std::mt19937 rng;
std::uniform_int_distribution<int> numbers;
};
Now, I need to draw in a row n different values in [0..k[. I was looking for something in <random> allowing that, but either I am not able to find it, or such a thing does not exist yet. Is there a clever, more elegant way to proceed than calling my getRandNum function and repeat until I get n different values?
EDIT: to give an idea, in my program k is some thousands and n some tens.
This solution is not C++ specific but can be easily implemented in any language.
What you want is essentially shuffle numbers 0 to k and pick the first n numbers, where n <= k.
This can be done using a reservoir sampling algorithm. See this wikipedia link for the pseudocode.
Note that it is possible to get the n numbers without storing all k numbers and shuffling them. That is, it is possible to just use O(n) space, where n is the number of random numbers you wish to obtain, instead of O(k). The time complexity for this algorithm is O(k), if we assume generating the random number takes O(1) time.
If k is several thousands and n is tens, then a permutation generation is really not the best choise. But calling getRandNum is not what you want too, because it can return the same value several times.
One option is to generate random sequence all at once, checking that the numbers don't repeat. The easiest (and may be even the most efficient) way to achieve this is to use a set.
Like so:
#include <vector>
#include <set>
#include <iostream>
#include <random>
class Random
{
public:
Random() : rng( rd() ) { }
inline int getRandNum( int limit ) { return ( numbers(rng) % limit ); }
std::set<int> getRandSequence(int limit, int n);
private:
std::random_device rd;
std::mt19937 rng;
std::uniform_int_distribution<int> numbers;
};
std::set<int> Random::getRandSequence(int limit, int n)
{
std::set<int> generatedSequence;
while (generatedSequence.size() < n) //size() for set is O(1) if I'm not mistaken
generatedSequence.insert(getRandNum(limit));
return generatedSequence;
}
int main()
{
Random r;
auto sequence = r.getRandSequence(1000, 10);
std::cout << "Seq;uence: " << std::endl;
for (int number : sequence)
std::cout << number << std::endl;
std::cout << "End" << std::endl;
return 0;
}
Ideone demo.
By the way, random_device creation is expensive, but uniform_int_distribution creation, as far as I remember, is not. So this might be even more efficient:
std::set<int> Random::getRandSequence(int limit, int n)
{
std::uniform_int_distribution<int> uiniformDistribution(0, limit);
std::set<int> generatedSequence;
while (generatedSequence.size() < n)
generatedSequence.insert(uiniformDistribution(rng));
return generatedSequence;
}
Besides, when you get a uniform distribution and then apply % limit to it, you don't get a uniform distribution anymore.
std::random_device rd; // obtain a random number from hardware
std::mt19937 eng(rd()); // seed the generator
std::uniform_int_distribution<> distr(0, 1500); // define the range
for(int a=0; a<limit; a++){
cout << distr(eng); //draw random nubmer

Generating pseudo-random uniformly-distributed integers in C++ [duplicate]

Is there a function for obtaining uniformly distributed pseudo-random integers in some specified range? I could write my own function using rand, but this seems like a common enough situation that there's probably something in the STL for it.
Boost provides many tools for random number generation.
For uniform distributions you have this one:
http://www.boost.org/doc/libs/1_49_0/doc/html/boost/random/uniform_real_distribution.html
EDIT: updated to include the new C++11 implementation. For the case of integers, here you have the reference:
http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
A simple example would be:
#include <random>
#include <iostream>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 6);
for(int n=0; n<10; ++n)
std::cout << dis(gen) << ' ';
std::cout << '\n';
}
To generate pseudo-random numbers in C++, a very good option is using the Mersenne twister pseudo-random number generator engine: std::mt19937 from the <random> header.
We can think of this engine as a black-box that spits out high-quality random bits.
Then, these random bits can be shaped in some integers output using a distribution; in particular, to get uniformly distributed pseudo-random numbers, a std::uniform_int_distribution can be used.
Note that the engine object must be initialized with a seed.
std::random_device can be used for that purpose.
So, this process can be summarized in three logical steps:
Create an instance of std::random_device, to get a non-deterministic seed for the Mersenne twister engine.
Create an instance of std::mt19937 engine, to get high-quality pseudo-random bits.
Use a std::uniform_int_distribution to shape these random bits in uniformly-distributed integers.
Compilable C++ code follows:
#include <iostream> // for console output
#include <random> // for pseudo-random number generators and distributions
int main()
{
// Use random_device to generate a seed for Mersenne twister engine.
std::random_device rd;
// Use Mersenne twister engine to generate pseudo-random numbers.
std::mt19937 engine(rd());
// "Filter" MT engine's output to generate pseudo-random integer values,
// **uniformly distributed** on the closed interval [0, 99].
// (Note that the range is [inclusive, inclusive].)
std::uniform_int_distribution<int> dist(0, 99);
// Generate and print 10 pseudo-random integers
for (int i = 0; i < 10; ++i)
{
std::cout << dist(engine) << ' ';
}
std::cout << std::endl;
}
For more details on generating pseudo-random numbers in C++ (including reasons why rand() is not good), see this video by Stephan T. Lavavej (from Going Native 2013):
rand() Considered Harmful
To generate one or specified number of random variables with uniform distribution on integer domain using std::generate_n and boost:
#include <iostream>
#include <algorithm>
#include <boost/random.hpp>
/*
*
*/
int main(int argc, char** argv) {
boost::mt19937 rand_generator(std::time(NULL));
boost::random::uniform_int_distribution<> int_distribution(0, 100);
//Need to pass generator
std::cout << int_distribution(rand_generator) << std::endl;
//Associate generator with distribution
boost::random::variate_generator<boost::mt19937&,
boost::random::uniform_int_distribution<>
> int_variate_generator(rand_generator, int_distribution);
//No longer need to pass generator
std::cout << int_variate_generator() << std::endl;
std::generate_n( std::ostream_iterator<int>(std::cout, ","), 3, int_variate_generator);
return 0;
}

How to fill an array with random floating point numbers?

I'm hoping to find a way to fill an array with random floating point numbers. My array is size 50 and I'm hoping to fill this array with random float numbers from range 1-25. Here is what I have so far. I greatly appreciate any tips or answers anyone can offer. Thank you.
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
float myArray[50];
for(int i = 1; i <= 25; i++)
{
srand(time(0));
myArray[i] = (rand()% 50 + 1);
cout << myArray[i] << endl;
system("Pause");
return 0;
}
}
If C++11 is an option I would use the random header and uniform_real_distribution:
#include <iostream>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 e2(rd());
std::uniform_real_distribution<> dist(0, 25);
for (int n = 0; n < 50; ++n) {
std::cout << dist(e2) << ",";
}
std::cout << std::endl ;
}
Why do people say there is modulo bias when using a random number generator? explains why the naive use of modulus with rand() causes bias in the distribution and how to avoid it.
If C++11 is not an option, you can just use rand, dividing its result by the RAND_MAX constant casted to float to obtain a uniform distribution of floats in the range [0, 1]; then you can multiply it by 24 and add 1 to get your desired range:
myArray[i] = rand()/float(RAND_MAX)*24.f+1.f;
By the way, as other observed, move srand out of your loop - the RNG seed (normally) must be initialized only once.
(notice that dividing by RAND_MAX will give a distribution that includes the right extreme of your interval; if you want to exclude it, you should divide by e.g. RAND_MAX+1)
Of course, the resulting distribution is only as good as the original rand() distribution (both in randomness and in granularity); you will typically get a LCG and granularity of at least ~0.0007 (guaranteed by the standard, and what VC++ and other compilers actually provide). If you need better random numbers, you should follow the advices posted in the other answers (the default Mersenne twister generator in C++11 provides better randomness and a way bigger guaranteed range).
#include <random>
...
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<float> dist(1.0f, 25.0f);
std::cout << dist(gen);
Each time the for loop iterates, it assigns one value in the array a random number. Since your array is of size 50, you want to iterate 50 times instead of 25 like you do now.
for(int i = 0; i < 50; i++)
Array bounds start at 0, so you can only access from array[0] to array[49].
To get a random number from 1-25, you want
myArray[i] = rand() % 25 + 1;
Also, do you want integers or floating point random numbers? Right now you are just getting integers, meaing 1, 2, 3, ... 25. If you want something like 2.45, 6.883, 23.999, etc. you need to do something different. See C++ random float number generation for the answer.
You probably don't want to pause every time you insert a number into the array. Move this after the for loop.
system("pause");
Also, if you return 0 inside the for loop, you will only assign one number before your program will exit. Move that to after the loop as well.
Use uniform_real. In the following program random float numbers between 1.0 and 2.0 are generated:
#include <random>
#include <iostream>
typedef std::ranlux64_base_01 Myeng;
typedef std::uniform_real<float> Myceng;
int main()
{
Myeng eng;
Myceng ceng(1.0, 2.0);
Myceng::input_type engval = eng();
std::cout << "a random value == " << ceng(eng) << std::endl;
std::cout << "a random value == " << ceng(eng) << std::endl;
std::cout << "a random value == " << ceng(eng) << std::endl;
return (0);
}

What's the standard way for getting uniformly distributed random integers in C++?

Is there a function for obtaining uniformly distributed pseudo-random integers in some specified range? I could write my own function using rand, but this seems like a common enough situation that there's probably something in the STL for it.
Boost provides many tools for random number generation.
For uniform distributions you have this one:
http://www.boost.org/doc/libs/1_49_0/doc/html/boost/random/uniform_real_distribution.html
EDIT: updated to include the new C++11 implementation. For the case of integers, here you have the reference:
http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
A simple example would be:
#include <random>
#include <iostream>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 6);
for(int n=0; n<10; ++n)
std::cout << dis(gen) << ' ';
std::cout << '\n';
}
To generate pseudo-random numbers in C++, a very good option is using the Mersenne twister pseudo-random number generator engine: std::mt19937 from the <random> header.
We can think of this engine as a black-box that spits out high-quality random bits.
Then, these random bits can be shaped in some integers output using a distribution; in particular, to get uniformly distributed pseudo-random numbers, a std::uniform_int_distribution can be used.
Note that the engine object must be initialized with a seed.
std::random_device can be used for that purpose.
So, this process can be summarized in three logical steps:
Create an instance of std::random_device, to get a non-deterministic seed for the Mersenne twister engine.
Create an instance of std::mt19937 engine, to get high-quality pseudo-random bits.
Use a std::uniform_int_distribution to shape these random bits in uniformly-distributed integers.
Compilable C++ code follows:
#include <iostream> // for console output
#include <random> // for pseudo-random number generators and distributions
int main()
{
// Use random_device to generate a seed for Mersenne twister engine.
std::random_device rd;
// Use Mersenne twister engine to generate pseudo-random numbers.
std::mt19937 engine(rd());
// "Filter" MT engine's output to generate pseudo-random integer values,
// **uniformly distributed** on the closed interval [0, 99].
// (Note that the range is [inclusive, inclusive].)
std::uniform_int_distribution<int> dist(0, 99);
// Generate and print 10 pseudo-random integers
for (int i = 0; i < 10; ++i)
{
std::cout << dist(engine) << ' ';
}
std::cout << std::endl;
}
For more details on generating pseudo-random numbers in C++ (including reasons why rand() is not good), see this video by Stephan T. Lavavej (from Going Native 2013):
rand() Considered Harmful
To generate one or specified number of random variables with uniform distribution on integer domain using std::generate_n and boost:
#include <iostream>
#include <algorithm>
#include <boost/random.hpp>
/*
*
*/
int main(int argc, char** argv) {
boost::mt19937 rand_generator(std::time(NULL));
boost::random::uniform_int_distribution<> int_distribution(0, 100);
//Need to pass generator
std::cout << int_distribution(rand_generator) << std::endl;
//Associate generator with distribution
boost::random::variate_generator<boost::mt19937&,
boost::random::uniform_int_distribution<>
> int_variate_generator(rand_generator, int_distribution);
//No longer need to pass generator
std::cout << int_variate_generator() << std::endl;
std::generate_n( std::ostream_iterator<int>(std::cout, ","), 3, int_variate_generator);
return 0;
}