Large unique random number generator

Hi all, I want to generate any random integer from 1 million to 30 million, so here is the code I've written.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
int digit[7];
long int id=0;
int main()
{
    srand(time(NULL));
    for (int n=1; n<100000; n++)
    {
        digit[6]=rand()%29+1; //1,XXX,XXX to 30,XXX,XXX
        for (int i=5; i>=0; i--) {digit[i]=rand()%10+1;} //Other digits
        id=digit[6]*pow(10,6)+digit[5]*pow(10,5)+digit[4]*pow(10,4)+digit[3]*pow(10,3)+digit[2]*pow(10,2)+digit[1]*10+digit[0]; //Summation
        cout << id << "\n";
    }
    return 0;
}


It works seemingly good. However if I want all the numbers to be unique, do I have to store all results in a list (array), then check if any new integer generated is the same as any on the list, and discard it if it is? I need to generate a large quantity of numbers, say tens of thousands. Is there any better way?
Last edited on
You create multiple numbers in ranges [1..30] and [1..10] in order to create one number in range [1'000'000..30'000'000].
(Except that you don't allow any 0 within the XXX'XXX. Furthermore, the first numbers could be 30 and 10, which makes 31 million and change.)

You could create the one number with a RNG single call. Preferably with <random> http://www.cplusplus.com/reference/random/uniform_int_distribution/

However, you do have an additional requirement: unique values.
Think of a new deck of cards. Every card is unique, but they are neatly ordered.
What do the dealers do first? They shuffle the deck.
The cards are still unique, but in random order.

The standard library has:
http://www.cplusplus.com/reference/vector/vector/
http://www.cplusplus.com/reference/numeric/iota/
http://www.cplusplus.com/reference/algorithm/shuffle/
Last edited on
Hm. Not sure why you use arrays for the job :/ when a simple function and variables will do. I see you are using long type, and thats a good thing.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <cstdlib>
#include <ctime>

using namespace std;

int main ()
{
srand (time (0));
//or you can use srand (time (NULL));

long int randNum , randMax , randMin;

randNum =
rand () % (randMax - randMin) + randMin;

return 0;
}


To generate random number between 30mil and 1mil, just initialize as follows:
1
2
3
long int randNum;
long int randMax = 30000000;
long int randMin = 1000000;

and then just do the other operation, initializing randNum as instructed.
Hope I helped!
To ensure uniqueness, put the numbers in a std::set. Then to generate a unique number, just loop until you get a number that isn't already in the set.
For unique numbers I would use a std::set. http://www.cplusplus.com/reference/set/set/
I'd just keep inserting to the set until the size() reached the required quantity.
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
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <unordered_set>

using namespace std;

long generate1()
{
    static const int p6 = 1e6;
    static const int p5 = 1e5;
    static const int p4 = 1e4;
    static const int p3 = 1e3;
    static const int p2 = 1e2;
    static const int p1 = 1e1;
//  static const int p0 = 1e0;

    static int digit[7];
    
    digit[6] = rand() % 30 + 1;
        
    for (int i=5; i>=0; i--) 
        digit[i] = rand() % 10 + 1;
       
    return digit[6] * p6 
         + digit[5] * p5
         + digit[4] * p4 
         + digit[3] * p3 
         + digit[2] * p2 
         + digit[1] * p1 
         + digit[0];    
}

int main()
{    
    srand(time(NULL));
       
//    const int size = 100000;
    const int size = 10;

    std::unordered_set<long> randoms;    
    
    while (randoms.size() < size)
        randoms.insert(generate1());
     
    for (auto & num : randoms)
        cout << num << '\n';
}

I want to generate any random integer from 1 million to 30 million

Your algorithm can generate numbers in excess of 30 million. When adding, there can be a carry from the previous column.

In a quick test I got values up to 31,110,480.
Topic archived. No new replies allowed.