Faxsy
Faxsy

Reputation: 361

Generate random numbers without duplicates in a dynamic array C

I want to randomize a dynamic array , with random numbers without duplicates in each column , and each column is limited ,

Check my main.c File

int main()
{
        int i, j;
        int **p;

        srand(time(0));

        p = malloc(9 * sizeof *p);
        for (i=0; i<9; i++) {
                p[i] = malloc (9 * sizeof *p[i]);
        }
        if (errno) {
                perror("startup");
                exit(1);
        }

        for (j=0; j<3; j++) {
                for (i=0; i<9; i++) {
                        p[j][i] = random(j,i);
                }
        }

        for (j=0; j<3; j++) {
                for (i=0; i<9; i++) {
                        printf(" %d ", p[j][i]);
                }
                printf ("\n");
        }
} 

and this is my random function

int random(int *j, int *i)
{
int s = 0;
int b;
int MIN =0;
int MAX=0;
b= i;

switch (b)
{

    case 0:
            MAX = 9;
            MIN = 1;
            s = (rand() % (MAX - MIN + 1)) + MIN;

    break;

case 1:
        MAX = 19;
        MIN = 10;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

case 2:
        MAX = 29;
        MIN = 20;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

case 3:
        MAX = 39;
        MIN = 30;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

case 4:
        MAX = 49;
        MIN = 40;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

case 5:
        MAX =59;
        MIN = 50;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

case 6:
        MAX = 69;
        MIN = 60;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

case 7:
        MAX = 79;
        MIN = 70;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

case 8:
        MAX = 90;
        MIN = 80;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

}
return s;
}

so Now I want to have any other way to do it but I must use dynamic allocation please suggest me anything that can help me out .

Upvotes: 1

Views: 1781

Answers (3)

pjs
pjs

Reputation: 19855

To avoid duplicates there are two basic approaches - 1) shuffle the entire set and pick a suitable subset from the front, or 2) generate random values, reject and re-try if you get a duplicate. Option 2 isn't as bad as it sounds if you're sampling only a few things from the range, but option 1 is easily the winner if the number of values is more than about square root of the range.

You can lose the switch statement. Since your ranges are going up as multiples of i, just use that fact to determine the MAX and MIN values:

if (0 == i) {
  MIN = 1;
  MAX = 9;
} else {
  MIN = 10 * b;
  MAX = MIN + 9;
}
s = (rand() % (MAX - MIN + 1)) + MIN;

Upvotes: 1

fernando.reyes
fernando.reyes

Reputation: 598

If you really need a real random number generator that don't repeat numbers, that won't be random at all :-),

The best way to do it is to create a list as long as you need it, with the unrepeated random numbers you need and then put them in random order.

-- edit --

If you're generating X numbers from 1 to 99, I'd do the next algorithm:

  • Generate the list of numbers from to 1 to 99, and put them on array N.
  • for i = 1 to X, s = rand(S), take number s from array N
  • Once you selected X different numbers from your array, you're done.

Do you think that'd work for you? It's easy, fast, and complies what you want.

Upvotes: 0

unwind
unwind

Reputation: 399823

I would suggest some changes:

  • Allocate the entire matrix with a single allocation, it's easier. It will mean that you must do the indexing manually (i.e. matrix[y * width + x]) but that's usually not too hard.
  • It seems you have very tight requirements for the numbers to appear in each column. I would suggest pre-seeding the matrix with all the numbers in sequence, then random shuffling. It's often easier than eliminating dupes.

Upvotes: 2

Related Questions