Hello, I am trying to fill an array with 20 unique random values between 1 and 60. I know what I need to do to get this to work, but I'm not sure how to do it. Here's what I've got:

void fillArray( int arr[], int size)
{
    int arr2[20];
    bool found[20] = {false};

    for (int i = 0; i < size; i++)
    {
        arr[i] = rand() % 60 + 1;
        arr2[i] = arr[i];

        for (int j = 0; j < size; j++) // check for duplicates in array
        {
            if (arr[i] == arr[j])
            {
                found[i] = true;
                arr[i] = rand() % 60 + 1;
            }
        }
    }
}

My program checks an array for duplicates, but doesn't check the duplicates to see if they themselves are duplicates. How might I go about doing that? Thank you for your time!

Dani AI

Generated

You do not need to hunt duplicates at all. As @iamthwee hints and outlines, the simplest correct model is “sample without replacement.” In modern C++, build the pool 1..60, shuffle it once using a real PRNG, and copy the first 20. That is exactly the Fisher-Yates idea sketched, but expressed with the standard library and a better engine than rand().

#include <algorithm>
#include <array>
#include <numeric>
#include <random>

void fill_unique(int out[], int n) {
    if (n > 60) return;                 // guard: cannot pick more than 60 unique
    std::array<int,60> pool;
    std::iota(pool.begin(), pool.end(), 1);     // 1..60

    std::mt19937 rng(std::random_device{}());   // seed a good engine
    std::shuffle(pool.begin(), pool.end(), rng);

    std::copy_n(pool.begin(), n, out);          // first n are unique and random
}

Notes and quick fixes:

  • If you must stay close to your original approach, at least only compare against values you have already chosen: change the inner loop to for (int j = 0; j < i; ++j) and, on a duplicate, redo the same i by doing --i; break;. But this is slower and trickier to get right.
  • Prefer std::shuffle over std::random_shuffle (the latter is deprecated/removed). rand() % 60 + 1 can introduce bias and still leaves you with duplicates to manage.
  • ’s boolean-used array works too, but it can loop many times when the array is nearly full. Shuffling once is O(60) and done. If you are on C++17, std::sample can pick 20 without shuffling all 60, which is nice when the range is large.

Recommended Answers

All 4 Replies

Member Avatar for Member #46692

This question has been asked many many times before.

The idea is to use std::random_shuffle.

So populate an array with values 1 through to 60.

Then shuffle the indexs as many times as you wish ( this involves picking two elements and swapping them.)
When you've finished you should have an array of random values ranging from 1-60.

Set up an array with the values 1-MAX (array[MAX], MAX being 60)
set up a loop with index 1 to 20
    get random number from 0 to MAX-index
    use that number as index into array to store the next number
    loop from MAX-index to MAX-2 and shuffle all contents down 1 entry

Not sure if it's just because I just woke up, but a few questions:
1. What is arr2 for?
2. Do you think the inner loop should really go all the way to the end? i don't :P

maybe you could leave the inner loop out.
make a boolean boolArray[SIZE=60] ( reset to false ) and perform a while loop

lets say you started looping , and randomized a number.
now check if boolArray[randomizedNumber] = false then you havent used this number
and can use it in the array[currentPlace] and you can move the currentPlace++.
(don't forget to update the boolean array)
and if it is true just don't go into the IF statement and the loop will just rendomize
a new Value.

hope I didn't help too much :O

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.