0
int i,j,vec[15]={0};
srand (time(NULL));
 for (i=0;i<15;i++){
     vec[i]=rand() % 25+1;      
    for (j=0;j<15;j++){
        if (i!=j){
            while(vec[i]==vec[j]){
                vec[i]=rand() % 25+1;
                }
            }
        }
         printf("%d\n",vec[i]);
     }




return 0;
}

the code still gives me repeated numbers

EXAMPLE: 24 3 7 20 18 10 12 17 9 7 4 25 13 15 21

I cant figure out what to do with it

  • 1
    you have to rerun the whole loop until you do not need to make a change. – wimh Nov 02 '14 at 16:55
  • 1
    btw, strange way to indent your code. For me it is difficult to read. – wimh Nov 02 '14 at 16:57
  • this line segment: rand() % 25+1; do you mean: (rand() % 25)+1; ? – user3629249 Nov 02 '14 at 20:13
  • all references to '15' in your code, except the line that declares vec[] should be written as sizeof(vec)/sizeof(int) so the size of the vec array, when changed, only needs to be changed in one place. – user3629249 Nov 02 '14 at 20:15
  • just because the code fixed one duplicate, does not mean the new value isn't a duplicate of another entry in the vec[] array. so the code needs to restart the search for duplicates when ever it changes some value. – user3629249 Nov 02 '14 at 20:19
  • Please analyze your algorithm, in case if your array is big your while loop will run until you find the last number you need. The probability decreasing with the increase of the arrays size. – AlexTheo Nov 02 '14 at 21:30

5 Answers5

0

Reset j in the while loop:

    for (j=0;j<i;j++){ //Use j<i 
        if (i!=j){
            while(vec[i]==vec[j]){
                vec[i]=rand() % 25+1;
                j=-1;//-1 because in the next iteration,j will start from 0
                }
            }
        }
Spikatrix
  • 20,225
  • 7
  • 37
  • 83
0

You can use an array

int randNumbers[25]; // fill it starting 0 to 25 then randomize the number in a range between 0 and 25 after swap the number in the randomized index with the last number in your array

randomize 0 to 23 and so on....

int main(int argc, char **argv) {    
    static const int size = 25;
    int numbers[size];
    for( int i = 0; i < size; i++ ){
      numbers[i] = i;
    }

    srand (time(NULL));
    for( int i = 0; i < size; i++ ){
      int rIndex = rand()%(size - i);
      int rNum = numbers[rIndex];
      numbers[rIndex] = numbers[size-i];
      printf("%d ", rNum);
    }

    return 0;
}

O(n) complexity...

AlexTheo
  • 4,004
  • 1
  • 21
  • 35
0

You have your loops mixed up. The logic is: Generate a random number until you have found one that isn't in the list.

The way you do it, you generate a new number inside the checking loop. But that doesn't work. Say you're generating the 4th number and find it is equal to the third. Then you generate a new one which might well be equal to any you have already checked against.

You also check uninitialised elements when j > i. Your inner loop should only run up to i.

So:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main()
{
    int vec[15] = { 0 };
    int i, j;

    srand(time(NULL));

    for (i = 0; i < 15; i++) {
        int okay = 0;

        while (!okay) {
            vec[i] = rand() % 25 + 1;
            okay = 1;

            for (j = 0; j < i; j++) {
                if (vec[i] == vec[j]) okay = 0;
            }
        }
        printf("%d\n", vec[i]);
    }

    return 0;
}

That still looks a bit awkward with that okay variable. In my opinion, checking for duplicates should be a separate function:

int contains(int arr[], int n, int x)
{
    while (n--) {
        if (arr[n] == x) return 1;
    }

    return 0;
}

int main()
{
    // snip ...

    for (i = 0; i < 15; i++) {
        do {
            vec[i] = rand() % 25 + 1;
        } while (contains(vec, i, vec[i]));

        printf("%d\n", vec[i]);
    }

    // snip ...
}

In your case the range of possible numbers isn't mich bigger than the number of array elements. You could also create an ordered array {1, 2, 3, ..., 25}, then shuffle it and use only the first 15 elements.

Community
  • 1
  • 1
M Oehm
  • 28,726
  • 3
  • 31
  • 42
  • imagine an array of billion of elements when you are on the last element which hast to be generated you will have a problem that the probability to get this element is 1/billions. So you will end up with the loop (almost infinity loop). – AlexTheo Nov 02 '14 at 20:27
  • @AlexTheo: The solution addresses the question which is about populating an array of 15 elements with unique numbers from 1 to 25. It is also modelled on what the user tried to do in the first place. The overhead of re-generating the numbers is small in this case, even for the last entry where there is a 14/25 chance to miss. I've also pointed the OP to the possibility of shuffling. – M Oehm Nov 03 '14 at 06:12
0

Are you actually trying to shuffle the numbers, rather than fill the array with randoms? (It looks like you want an array with numbers from 1 to 25, but in random order.) rand() can give you duplicate numbers (they're random, after all!)

Try this:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

int
main( int argc, char **argv )
{
    int  i, vec[25];

    for (i = 0; i < 25; ++i) vec[i] = i + 1;

    /* Shuffle entries */
    srand( time( 0 ) );
    for (i = 0; i < 1000; ++i) {
        int a = rand( ) % 25;
        int b = rand( ) % 25;
        if (a != b) {
            int tmp = vec[a];
            vec[a] = vec[b];
            vec[b] = tmp;
        }
    }

    /* Print shuffled array */
    for (i = 0; i < 25; ++i) printf( "%d: %d\n", i, vec[i] );
    return 0;
}
Dave M.
  • 1,496
  • 1
  • 12
  • 30
0
#include<stdio.h>
#include<stdlib.h>

int inArray(int, int, int*);

int main()
{

    int i,j,vec[15]={0};
    int temp;
    srand (time(NULL));
    for (i=0;i<15;i++){
        temp =rand() % 25+1;      
        while(inArray(i+1,temp, vec) == 1){
            temp = rand() % 25+1;
        }
        vec[i] = temp;
        printf("VECT[%d]  \t=  %d\n",i,vec[i]);
    }
    return 0;
}

int inArray(int count, int input, int* array){
    int i = 0;
    for(i=0; i<count; i++){
        if(input == array[i]){
            return 1;
        }
    }
    return 0;
}

Gave an output:

VECT[0]         =  24
VECT[1]         =  19
VECT[2]         =  1
VECT[3]         =  25
VECT[4]         =  22
VECT[5]         =  18
VECT[6]         =  7
VECT[7]         =  8
VECT[8]         =  12
VECT[9]         =  21
VECT[10]        =  11
VECT[11]        =  6
VECT[12]        =  23
VECT[13]        =  20
VECT[14]        =  15

The checking was off, you would change and not break allowing it to be changed to a previous value.

Hashman
  • 151
  • 5