Generating different random numbers

Jan 6, 2013 at 3:36pm
I have a loop that will generate 10 random numbers between 1 and 25 and then insert in into an array but I cant figure out how to make it so that the 10 numbers are different.

So any thing I can try?
Jan 6, 2013 at 3:38pm
For example you can use std::bitset<25> to trap what random numbers were already generated.
EDIT: Another way is to check the array whether it contains already the number by traversing the array.
Last edited on Jan 6, 2013 at 3:41pm
Jan 6, 2013 at 3:40pm
closed account (o3hC5Di1)
Hi there,

C++11 has a new <random> library that will provide you with all the tools you need.
For an overview and an example of generating random numbers within a given range see: http://cplusplus.com/reference/random/

Do let us know if you require any further help.

All the best,
NwN
Jan 6, 2013 at 3:48pm
Alas I am restricted to having to use 2010 version, this is what I currently have:

for (count = 0; count < 11; count++)
{
mine_placer[count] = rand() % 26;
}

And I am unsure on what is meant by the bitset function as I am new to C++
Jan 6, 2013 at 3:52pm
A_ Every time you generate a number, you check that that number was not previously generated.

1_ Shuffle an array of 25 elements, initialized from 1 to 25. Take the first 10.


(1_ is guaranteed to end)
Edit: for (count = 0; count < 11; count++) those are 11 numbers...
Last edited on Jan 6, 2013 at 3:54pm
Jan 6, 2013 at 3:57pm
@f186751


This code

1
2
3
4
for (count = 0; count < 11; count++)
 {
 mine_placer[count] = rand() % 26;
 }


is already invalid. In fact you are dealing with an array having 11 elements. And random numbers you will get will be in the range 0 - 25 but you are required to generate random numbers in the range 1 - 25.
Last edited on Jan 6, 2013 at 3:57pm
Jan 6, 2013 at 6:13pm
An alternate approach:
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
31
32
33
34
35
36
37
38
39
#include <set>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>

unsigned getRandom(unsigned min, unsigned max)
{
    const unsigned range = max - min + 1 ;
    return rand() % range + min ;
}

void print(unsigned* a, unsigned elements )
{
    std::cout << "{ " ;
    for ( unsigned i=0; i < elements; ++i )
        std::cout << *a++ << ' ' ;
    std::cout << "}\n" ;
}

int main()
{
    srand(time(0)) ;

    const unsigned uniqueNumsToGenerate = 10 ;
    const unsigned randMin =  1 ;
    const unsigned randMax = 25 ;

    std::set<unsigned> nums ;

    while ( nums.size() < uniqueNumsToGenerate )
        nums.insert(getRandom(randMin,randMax)) ;

    unsigned array[uniqueNumsToGenerate] ;

    std::copy(nums.begin(), nums.end(), array) ;

    print(array, uniqueNumsToGenerate) ;
}


Of course, it has the (possible) disadvantage of the random numbers being sorted. If that's not acceptable for your use case, shuffling the resulting array would be in order.
Jan 6, 2013 at 6:48pm
closed account (D80DSL3A)
Yet another method...

The STL and C++11 are terrific, but what happens if no canned solution method seems evident?

Write your own???
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
31
32
33
34
35
36
int main()
{
    const int sizeA = 25;
    int A[sizeA];// contains the set of unique values
    int i=0;

    for(i=0; i<sizeA; ++i)
        A[i] = i + 1;//1 2 3 4...

    const int sizeB = 10;
    int B[sizeB];// result storage

    // When a value is selected, remove it from the pool of values being selected from
    // swap sizeB randomly selected elements from "left end" of A to the "right end" of A
    // left/right split is at A[idxSplit]
    int idxSplit = sizeA - 1;
    for( i=0; i<sizeB; ++i )
    {
        int idxRand = rand()%( 1 + idxSplit );// random index into "left portion" of A
        int temp = A[idxRand];// swap values
        A[idxRand] = A[idxSplit];
        A[idxSplit] = temp;
        --idxSplit;

        // catch the unique value just swapped (or copy from A[idxSplit+1] to A[sizeA-1] later)
        B[i] = temp;
    }

    // show the B array
    cout << "B: ";
    for( i=0; i<sizeB; ++i )
        cout << B[i] << " ";

    cout << endl;
    return 0;
}

Output:

B: 17 12 10 13 18 5 3 1 21 25

Actually, this method is more generally useful than this case suggests.
Sometimes the problem is to use a subset of specific values. Example:
A[] = { 1, 2, 3, 5, 7, 11, 13,... } could be used to support filling B with randomly selected unique prime numbers.

EDIT: If you are using all values in A, but you need them randomly shuffled then replacing line 17:
for( i=0; i<sizeB; ++i ) with
for( i=0; i<(sizeA-1); ++i ) would accomplish that on A itself (ie, no need for B).
A: 22 9 19 14 23 16 20 11 8 2 7 4 24 15 6 25 21 1 3 5 18 13 10 12 17


Of course, calling random_shuffle (from STL) on A[] would work fine too (sigh).

I guess that makes this my solution:
1
2
3
4
5
6
7
8
9
10
11
12
13
template<class T>
void myRandomShuffle( T A[], unsigned size )
{
    int idxSplit = size - 1;
    while( idxSplit > 0 )
    {
        int idxRand = rand()%( 1 + idxSplit );
        T temp = A[idxRand];// swap values
        A[idxRand] = A[idxSplit];
        A[idxSplit] = temp;
        --idxSplit;
    }
}

Last edited on Jan 6, 2013 at 8:11pm
Topic archived. No new replies allowed.