random number generator without duplicate

I'm trying to generate random number without repeating same number...



#include<iostream>
#include<string>
#include<ctime>
#include<random>
using namespace std;
int ** gen2Array(int n);
void randomFillUnique(int **a, int n);

int main()
{
int n;
cout << "Enter a N number for size of the n x n array: ";
cin >> n;
cout << endl;
int** result = gen2Array(n);
randomFillUnique(result, n);
cout << "Generated array : " << endl;
for (int i = 0; i<n; i++)
{
for (int j = 0; j<n; j++)
{
cout << result[i][j] << "\t";
}
cout << endl;
}
system("pause");
return 0;
}
int ** gen2Array(int n)
{
int **p;
p = new int*[n];
for (int i = 0; i < n; ++i)
{
p[i] = new int[n];
}
return p;
}
void randomFillUnique(int **a, int n)
{
static default_random_engine e(static_cast<unsigned>(time(NULL)));
uniform_int_distribution<int> u(1, (100));

for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
a[i][j] = u(e);

}
}
}
Check if the number has already been used using an alternative data structure like a hash table, if the number has been generated before, generate another number and repeat if it has been used too.
What is your problem?
Something like this.
This is in C++/Qt, adjust to your language.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    QList<uint> numList;
    uint num;
    bool duplicate;

    //generate your seed here

    for (uint i = 0; i < qty; i++)
    {
        do {
            num = (generate your random number);
            if (numList.contains(num))
            {
                duplicate = true; // skip duplicates
            }
            else
            {
                numList.append(num);
                duplicate = false;
            }
        } while (duplicate);
    }
Last edited on
Apart from the strategy, this issue too:
1
2
3
4
uniform_int_distribution<int> u( 1, 100 );

for (int i = 0; i < n; i++)
   for (int j = 0; j < n; j++)

There are 100 unique values in the distribution. n*n will be used. Therefore, n larger than 10 is not possible.


gunnerfunner's answer is the way to go here. First take enough unique values (imagine a "deck" of unique "cards"). Then pull values/cards from the deck. *However, a dealer does not draw a card randomly; dealer draws the first card from an already shuffled deck.
A possibility, though it can be inefficient when the possible random numbers is similar to the number of values to be generated.

1
2
3
#include <ctime>
#include <random>
#include <unordered_set> 


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
void randomFillUnique(int **a, int n)
{
    static default_random_engine e(static_cast<unsigned>(time(NULL)));
    uniform_int_distribution<int> u(1, 100);

    size_t size = n * n;
    
    std::unordered_set<int> randoms;
        
    if (size > 100)
    {
        cout << "size " << size << " is too large\n";
        return;
    }
    
    while (randoms.size() < size)
    {
        randoms.insert( u(e) );
    }
    
    std::unordered_set<int>::iterator it = randoms.begin();
    
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            a[i][j] = *it++;
        }
    }
}
Like gunnerfunner said, shuffle an array/vector that has all the values 1-100.

<algorithm> ~ std::random_shuffle()

http://www.cplusplus.com/reference/algorithm/random_shuffle/
Note: the std::random_shuffle has already been deprecated, because it relies on deprecated rand. The OP is already using the new <random> and should thus choose the std::shuffle instead.

Another note about:
1
2
3
4
5
6
7
8
9
10
int ** gen2Array(int n)
{
  int **p;
  p = new int*[n];
  for (int i = 0; i < n; ++i)
  {
    p[i] = new int[n];
  }
  return p;
}

All values of the array may not be in consecutive memory. Consider this alternative:
1
2
3
4
5
6
7
8
9
10
int ** gen2Array(int n)
{
  int **p = new int*[n];
  p[0] = new int[n*n];
  for ( int row = 1; row < n; ++row )
  {
    p[row] = p[0] + n * row;
  }
  return p;
}


And then the obligatory big one: where are your deletes?
Topic archived. No new replies allowed.