Suppose you need to generate random numbers within a specified range. The traditional method of accomplishing this task consists of using the ANSI C function random() and normalizing the result to ensure that it falls in the specified range. However, there are at least two problems with this technique. First, the normalization often tends to skew the results, so you don't get a truly random sequence of numbers (i.e., some numbers will occur more frequently than others). Secondly, random() applies to type int exclusively; you cannot use it to generate a random sequence of characters, float numbers, strings, or Employee records. C++ offers a much better alternative, namely, the random_shuffle() algorithm. In the following sections, I will show how to use this algorithm to generate random sequences of various types easily.
The best way to generate a random set of elements in a specified range is to create an ordered sequence (i.e., a vector or a built-in array) that contains all the values in that range. For example, if you need to generate 100 numbers in the range of 0 through 99, create a vector and fill it with 100 numbers in ascending order, as follows:
#include <vector>
using std::vector;
int main()
{
vector<int> vi;
for (int i = 0; i < 100; i++)
vi.push_back(i);
/*Now the vector contains 100 elements: 0-99 stored in
an ascending order*/
}
After filling the vector, you use the random_shuffle() algorithm to shuffle the order of its elements. random_shuffle() is defined in the standard header <algorithm>. Recall that all STL algorithms are declared in namespace std::. Therefore, you need an appropriate using-declaration. random_shuffle() takes two arguments, the first of which is an iterator that points to the first element of the sequence. The second argument is an iterator that points one position past the last element of the sequence. The following code snippet shuffles the elements of the previously filled vector:
#include <algorithm>
using std::random_shuffle;
random_shuffle(vi.begin(), vi.end()); /* shuffle elements */
If you examine the elements of the shuffled vector, you will see that they are stored in a random order:
for (int i = 0; i < 100; i++)
cout<<vi[i]; /* display shuffled elements */
random_shuffle() is completely genericit's applicable to built-in types and user-defined types alike. In the following example, I create of vector of 7 strings objects that contain the days of the week and use random_shuffle() to shuffle their order:
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
vector<string> vs;
vs.push_back(string ("Sunday"));
vs.push_back (string ("Monday"));
//…fill the rest of the days
random_shuffle(vs.begin(), vs.end()); /* shuffle days */
for (int i = 0; i << 7; i++)
cout<<vs[i]; /* display shuffled elements */
}
Using random_shuffle() with Built-in Arrays
You shouldn't be concerned about the overhead of using containers instead of built-in arrays. All STL algorithms apply to sequences, not just containers. Thus, you can use random_shuffle() with built-in arrays as well. Make sure that the second argument of random_shuffle() points one element past the array bounds:
char carr[4] = {'a', 'b', 'c', 'd'};
/*carr+4 points one position past array bounds*/
random_shuffle(carr, carr+4);
for (int i = 0; i < 4; i++)
cout<<carr[i]; /* display shuffled elements */