hey guys,
I want to create 6 different random numbers without repetitions and this what I have done. I just wanted to make sure if this logic makes sense.

for(int n=0 ; n<6 ; n++)
	{
		randomInt[n] = generateRandomInt(0,20);
		cout << randomInt[n] << endl;
	}
	for(int i=0 ; i<6; i++)
	{
		for(int j=i+1 ; j<6 ; j++)
		{
			if(randomInt[i] == randomInt[j])
				randomInt[i]=generateRandomInt(0,20);
		}
		cout << randomInt[i] << endl;
	}
}

Dani AI

Generated

Short answer: you can only get 6 distinct numbers if the range actually contains at least 6 values. Picking 6 numbers from [0,4] (5 distinct values) must produce repeats. Also be explicit about bounds: “[0,100]” has 101 values, “[0,100)” has 100 — off-by-one mistakes are the common source of confusion here (this explains the behavior you saw, ).

’s shuffle idea is the simplest correct approach for moderate ranges. For modern C++ prefer std::shuffle with a proper engine (std::mt19937) and then take the first k elements; this avoids collisions and is unbiased. Example (for an inclusive [min,max]):

#include <vector>
#include <algorithm>
#include <random>
#include <numeric>

// fill vector with min..max, shuffle, take first k
int min = 0, max = 100, k = 5;
int N = max - min + 1;
// check k <= N before proceeding
std::vector<int> v(N);
std::iota(v.begin(), v.end(), min);
std::random_device rd;
std::mt19937 gen(rd());
std::shuffle(v.begin(), v.end(), gen);
// v[0]..v[k-1] are k distinct values

If you want to avoid allocating and shuffling the whole range when N is large, do the first k steps of Fisher–Yates (partial shuffle): for i in 0..k-1 pick j uniformly from i..N-1, swap v[i] and v[j], and output v[i]. This gives k unique picks with only k iterations.

Notes: do not rely on rand()/srand() for high-quality, unbiased results (and srand only seeds; it does not prevent repeats) — use <random> and std::uniform_int_distribution when you need uniformity. If k is tiny relative to N, simple rejection with an unordered_set can be fine; if k is close to N, use a shuffle/partial shuffle.

Recommended Answers

All 10 Replies

I see where you're trying to go with it, so I guess it does make sense. Why do you ask?

I ask because it works alright for larger range, but If I change the range to 0 to 4 instead of 0 to 20. I do get repetition. Is it possible to modify it a bit to get 100% no repetition?

Your easiest bet is to do a random shuffle of the range:

#include <algorithm>
#include <iostream>

int main()
{
  const int n = 4;
  int a[n];

  for ( int i = 0; i < n; i++ )
    a[i] = i;

  std::random_shuffle ( a, a + n );

  for ( int i = 0; i < n; i++ )
    std::cout<< a[i] <<'\n';
}

would that work for larger range, if change n to 100? My goal is to create 5 random numbers from 1 to 100 without repetition.

It'll work for any range, within reason. The limiting factor is storage for N integers, so when you want a range of [0,100000000), for example, the random shuffle solution becomes less useful.

so, how would I go about modify random shuffle code that you wrote, for 5 random numbers and range [0,100]?

>range [0,100]?
Just making sure, you want the range of 0 to 100, including both 0 and 100? There's a difference between [0,100] and [0,100), and that changes the code. For the latter it would be this:

#include <algorithm>
#include <iostream>

int main()
{
  const int n = 100;
  int a[n];

  for ( int i = 0; i < n; i++ )
    a[i] = i;

  std::random_shuffle ( a, a + n );

  for ( int i = 0; i < 4; i++ )
    std::cout<< a[i] <<'\n';
}

For the former, you would want to change the value of n to 101 so that 100 is included in the range.

You should revisit definition the of rand() and srand() functions,
both will give you non-repeating random numbers from 0 to your system's 'randmax' value.
Just use the standard form of rand() with a 'shift' and 'scale factor',eg:
number = shift value + rand() % scaling factor;
// shift value = minimum number
// scale factor = repeat point (What ever the modulus is chosen to be.)
For your code, simply populate your array with the numbers returned from the computation.
If your for loop conitunation limit is greater than the (shift value + scale factor), then the numbers will repeat in that range.

Try to keep your code simple, as you don't really need '2' for loops and all those 'if' tests.
Nice try just the same.

>both will give you non-repeating random numbers from 0 to your system's 'randmax' value.
Sorry, but that's incorrect. First, srand doesn't give you random numbers at all, it seeds the generator for rand to give you random numbers. Second, rand is not only allowed to repeat numbers, the very definition of random numbers makes repeating values expected.

Your solution doesn't address the problem, which is, for example, in the range of [0,100) the value 50 may appear more than once.

Your easiest bet is to do a random shuffle of the range:

#include <algorithm>
#include <iostream>

int main()
{
  const int n = 4;
  int a[n];

  for ( int i = 0; i < n; i++ )
    a[i] = i;

  std::random_shuffle ( a, a + n );

  for ( int i = 0; i < n; i++ )
    std::cout<< a[i] <<'\n';
}

yes, [0,100].
So, could I just modify it like the following?
std::random_shuffle ( a, a + 101 );

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.