C++11 Random library usage in lambdas
Nov 30, 2012 at 4:10pm UTC
Someone recently asked how to generate strings filled with random letters, so I suggested
std::generate() and C++11's
random library.
Later when I tried to write a solution myself, I realized that the program displays the same string every time it's run. (And also if recompiled without modifications.)
tl;dr: why isn't the output of this program random?
Using nuwen's MinGW 4.7.2 distribution.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
// http://cplusplus.com/forum/windows/86580/
#include <algorithm>
#include <cctype>
#include <functional>
#include <iostream>
#include <random>
#include <string>
int main()
{
const std::size_t defaultStringLength = 10;
std::default_random_engine prne;
std::uniform_int_distribution<char > uid('A' , 'z' );
auto randomCharacter = std::bind(uid, prne);
std::string s(defaultStringLength, ' ' );
std::generate(s.begin(), s.end(), [&randomCharacter]() -> char {
while (true )
{
const char c = randomCharacter();
if (std::isalpha(c))
return c;
}
});
std::cout << s << std::endl;
}
Nov 30, 2012 at 4:24pm UTC
Like always, you need to seed your RNG.
Nov 30, 2012 at 4:27pm UTC
Embarrassing.
@ Peter87: thanks for the reply.
Nov 30, 2012 at 5:50pm UTC
For variety, this could be done without a loop (but also without a lambda)
1 2 3 4 5
std::vector<double > bounds = {'A' , 'Z' +1, 'a' , 'z' +1};
std::vector<double > weights = { 1, 0, 1};
std::piecewise_constant_distribution<> d(bounds.begin(), bounds.end(), weights.begin());
std::generate(s.begin(), s.end(), bind(d, ref(prne)));
demo:
http://ideone.com/4JgKjf
Last edited on Nov 30, 2012 at 5:51pm UTC
Nov 30, 2012 at 6:32pm UTC
Topic archived. No new replies allowed.