Generate a random number with no repeating digits?


1
2
3
4
5
6
 I'd like to generate a random number with each digit being in range from 0-9 and not repeating itself. Assume finite length of 4.

4321 qualifies, each composite digit is unique.
1323 does not, 1 is repeated

How can this be done please? 
closed account (D80DSL3A)
I would generate the number one digit at time, using an array of 10 bools to keep track of which digits have been used. Several calls to rand() per digit may be needed after the 1st digit.
Then, use each uniquely generated digit to "build up" the 4 digit number.

Like this:
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
#include <iostream>
#include <cstdlib>// for rand()
#include<ctime>

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

   bool digitUsed[10] = {0};// to keep track of which digits have been used
   const int numDigits = 4;// this can be as high as 10
   int numIters = 1;// count # o times that rand() gets called.

   // 1st digit
   int x = rand()%10;// x will be the 4 digit number
   digitUsed[x] = true;

   for(int i = 1; i < numDigits; ++i )
   {
       int digit = 0;
       do// until unique digit generated
       {
           digit = rand()%10;
           ++numIters;
       }while( digitUsed[digit] );

       digitUsed[digit] = true;// mark this digit as used now
       x *= 10;// put a zero on the end
       x += digit;// becomes last digit
   }

   std::cout << "x = " << x << " in " << numIters << " calls to rand()." << std::endl;

	return 0;
}
closed account (D80DSL3A)
Of course, codewalkers suggested method makes the unique digit generation much easier!

I think his intent is along these lines:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <algorithm>

int main()
{
   int digits[] = {0,1,2,3,4,5,6,7,8,9};// list them all
   std::random_shuffle( digits, digits + 10 );// shuffle them. Will just use the 1st 4 for our number

   const int numDigits = 4;// this can be as high as 10

   // 1st digit
   int x = digits[0];// x will be the 4 digit number

   for(int i = 1; i < numDigits; ++i )
   {
       x *= 10;// put a zero on the end
       x += digits[i];// becomes last digit
   }

   std::cout << "x = " << x << std::endl;

	return 0;
}
#include <iostream>
#include <cstdlib>// for rand()
#include<ctime>

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

bool digitUsed[10] = {0};// to keep track of which digits have been used
const int numDigits = 4;// this can be as high as 10
int numIters = 1;// count # o times that rand() gets called.

// 1st digit
int x = rand()%10;// x will be the 4 digit number
digitUsed[x] = true;

for(int i = 1; i < numDigits; ++i )
{
int digit = 0;
do// until unique digit generated
{
digit = rand()%10;
++numIters;
}while( digitUsed[digit] );

digitUsed[digit] = true;// mark this digit as used now
x *= 10;// put a zero on the end
x += digit;// becomes last digit
}

std::cout << "x = " << x << " in " << numIters << " calls to rand()." << std::endl;

return 0;
}


This code is bad because sometimes ir generates 3 digits number.. Help!!!
closed account (D80DSL3A)
Those 3 digit numbers are actually 4 digit numbers in which the 1st digit = 0. The leading zero doesn't display.
I know there's an output manipulator which can be used to make the leading zero display, but I'd have to look it up. Writing this is quicker for me:
1
2
if( x < 1000 ) cout << '0';// insert a leading zero.
cout << x;


Maybe someone will share the other method I mentioned.
Last edited on
All you need is random_shuffle() (or shuffle(), and maybe a good RNG).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <algorithm>
#include <chrono>
#include <iostream>
#include <random>
#include <string>
using namespace std;

int main()
{
  const bool no_leading_zero = false;

  string n = "0123456789";

  shuffle( n.begin(), n.end(),
    mt19937( chrono::high_resolution_clock::now().time_since_epoch().count() )
    );
    
  if (no_leading_zero && (n[ 0 ] == '0'))
    n = n.substr( 1, 4 );
  else 
    n.resize( 4 );
  
  cout << n << endl;
}

BTW, your professor won't like this answer, because you probably don't know enough to have come up with it on your own.

Just another way of thinking about the problem.
Topic archived. No new replies allowed.