0

I'm now trying to: 1. Generate four number randomly. 2. Store them in array. 3. Make sure the value in array don't duplicate.

Here is my idea: 1. Generate one number each time in for loop (x4 times) 2. After generating number, using inner loop to compare it to the previous array value.

My code:

do
{ 
    for (int i = 0; i < 4; i++)
    {
        value[i] = rand() % 6 + 1;      // Generating value
        for (int j = 0; i > j; j++)
        {
            if (value[i] == value[j])
            {
                dup = true; break;
            }
            if (dup == true) break;
        }
    }

    for (int i = 0; i < 4; i++)
    {
        cout << "value: " << value[i] << " " << endl;
    }
} while (dup != true);

I was wondering why same array value will still be generating, as in my code, the loop will be repeating until no more duplicated value is found.

Edwardhk
  • 87
  • 3
  • 9

2 Answers2

0

In terms of why you're getting a duplicate result, it's because you're continuing to try again while (dup != true). Read that carefully: while there is not a duplicate, keep trying.

That means it will keep trying until there is a duplicate.


In any case, that sort of problem is generally best solved with a Fisher Yates shuffle but, for this small search space (four from six), you could get away with your scheme.

However, it's probably better done as checking each number against every previous number, along the lines of:

def getFourFromSix():
    num = []

    num.append (random(1..6))

    num.append (num[0])
    while num[1] == num[0]:
        num[1] = random(1..6)

    num.append (num[0])
    while num[2] == num[0] or num[2] == num[1]:
        num[2] = random(1..6)

    num.append (num[0])
    while num[3] == num[0] or num[3] == num[1] or num[3] == num[2]:
        num[3] = random(1..6)

    return num

That way, you're not actually going all the way back and restarting every time you find a duplicate, you only have to try again on the current number.


If you do want a Fisher Yates shuffle (and it's a little more elegant if the pool of numbers gets larger), an M-from-N variant is as simple as:

def getMFromN(m, n):
    # Sanity checking.

    if m > n:
        throw "Trying to extract too many things"

    num = []

    # Populate choices that we will select from.

    for index in 0..n-1:
        choice[index] = index + 1

    # For each desired number.

    for index in 0..m:
        # Copy from choices to results.

        choose = random(0..n-1)
        num.append (choice[choose])

        # Remove from results so no repeats.

        n = n - 1
        choice[choose] = choice[n]

    return num
Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Hello, thank you for your quick reply. I am learning Fisher Yates shuffle now, that was what I am looking for, much appreciated, thank you !!! – Edwardhk Jan 30 '16 at 04:11
0

There is a logical flaw in your code. By the time you're breaking from the loop you have already stored the duplicate value generated by rand into your 'value' array. You will have to either re-process the index until you don't get a duplicate -or- use a better data structure.

Why not use a set<int> that way it will only hold unique values and you can exit/break when you've populated N unique elements.

gusaki
  • 741
  • 7
  • 13