Filling array with unique numbers?

This is just a piece of the code. How can I make this not use the same number repeated times? The container has 7 slots and the numbers have to be in the interval of 1 - 35.
1
2
3
4
5
while(x <= 6)
{
tal[x] = rand()%35 + 1;
x++;
}
Last edited on
Bump anyone?
closed account (o1vk4iN6)
Use the container "set" where only one instance of any number can exist.
Can I get it to somehow repeat the step or something? If tal occurs multiple times?
Last edited on
closed account (D80DSL3A)
You could code around the problem directly, instead of relying on some "black box" container to do it.

I suggest something like:
1
2
3
4
5
6
7
8
9
10
11
12
int x = 0;
while(x <= 6)
{
    tal[x] = rand()%35 + 1;
    
    bool unique = true;
    for( int j=0; j<x; ++j )// check if that value exists in the array already
        if( tal[j] == tal[x] )
            unique = false;// skip incrementing x below and try again
    if( unique )
        x++;
}
Last edited on
closed account (o1vk4iN6)
Keep adding to the set while it isn't the size you want.
@fun2code You see, that's impossible, since it will be
if(tal[0] == tal[0])
because both int x; and int j; is 0. I tried it and my program skips creating any lines at all.
@AnEvilVegetable:
Quick fix:
1
2
if(x == j)
    continue;
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <set>
#include <vector>
#include <algorithm>
#include <stdexcept>

typedef std::vector<unsigned> v_type ;

v_type get_random_unique_vector(unsigned, unsigned, unsigned) ;

void display(const v_type&);

int main()
{
    std::srand(std::time(0)) ;

    const unsigned num_random =  7 ;
    const unsigned min =  1 ;
    const unsigned max = 35 ;
    for ( unsigned i=0; i<5; ++i )
        display(get_random_unique_vector(num_random, min, max)) ;
}

v_type get_random_unique_vector(unsigned n_values, unsigned min, unsigned max)
{
    if ( max-min+1 < n_values )
        throw std::logic_error("Really?") ;

    v_type v ;
    v.reserve(n_values) ;

    std::set<unsigned> randoms ;

    while ( v.size() < n_values )
    {
        unsigned num = rand() % (max-min+1-v.size()) + min ;

        while ( !randoms.insert(num).second )
            ++num ;

        v.push_back(num) ;
    }
    return v ;
}

void display(const v_type & v)
{
    for ( unsigned i=0; i<v.size(); ++i )
        std::cout << v[i] << ' ' ;
    std::cout << '\n' ;
}


As the number of values you're generating approaches the amount of numbers in your range (98 values, min 1, max 100 for example) it should become more efficient to fill the vector with all values in the range, shuffle it, and resize.


fill the vector with all values in the range, shuffle it, and resize

^ This.

Useful link -> http://www.cplusplus.com/reference/algorithm/random_shuffle/
I might be close to an solution. But the thing is, after tal[search]; has compared itself to tal[x] and both increases by one, tal[1] can still be what tal[0] was. Can I somehow add the numbers already taken into another array and then give the condition that the new number if identical can be everything BUT the ones in the array containing already used numbers?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int x = 0;
int search = 0;
	while(x <= 6) //Give int tal[7] 7 random numers
	{
		tal[x] = rand()%35 + 1;
			while(search < x) //Search if there's identical numbers
			{
				while(tal[x] == tal[search]) //Alternatively replace tal if identical so the same number doesn't appear multiple times
				{
					tal[x] = rand()%35 + 1;
				}
			search++;
			}
		search = 0;
		x++;
	}
@cire

That might work, but I have to explain what that does for the teacher, and I understand about 10% of that... I've just been programming for 5 months and the only thing I know is the basics, if-else and loops.
If you find a duplicate, don't increase x and just let the loop iterate again:

1
2
3
4
5
6
7
8
9
10
11
    while ( x <= 6 )
    {
        tal[x] = rand()%35 + 1;

        int search = 0 ;
        while ( search < x  && tal[x] != tal[search] )
            ++search ;

         if ( search == x ) // no duplicate found
            ++x ;
      }
Can I somehow add the numbers already taken into another array and then give the condition that the new number if identical can be everything BUT the ones in the array containing already used numbers?

Yes. Use an array of bools.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//...

bool alreadyUsed[36] = { false }; // everything is initialized to false

// ...

do
{
    tal[x] = rand() % 35 + 1;
} while (alreadyUsed[tal[x]]);

alreadyUsed[tal[x]] = true;

//... 
@cire

Now I see! THANKS mister! I finally understand! :D
Topic archived. No new replies allowed.