Question

I've written some code to generate an array of structures. The id variable is intended to be unique and generated randomly. However, what seems to be happening is that if the generate function (which gnerates and fills the array of structures) encounters a matching number in the array, the flag variable is set to 0 and it exits the do loop without create a new random number to recheck for a match. Then when the loop exits, the code goes ahead and assigns the matching random number to the empty spot in the array anyway. As a caveat, I realize it would be simpler to just take all 10 possible integers, move them around, and fill the array, but I'm trying to get the hang of rand() using a small sample so I can watch what it's doing in debugger. I suspect I've just been staring at this too long and tried too many things, but any suggestions would be appreciated. Thanks.

EDIT: Just to clarify my question specifically concerns the do loop and what I need to do to make sure that when a match is found, the program generates a new random number and begins searching again for a match. This should be repeated for each position in the array until each id element is unique. Currently, when I run the program, I'm still getting duplicate numbers.

#include <stdio.h>
#include<stdlib.h>
#include<math.h>
#include<conio.h>
#include<assert.h>

struct student{
    int id;
    int score;
};

struct student* allocate(){
     /*Allocate memory for ten students*/
    struct student* s = malloc(10 * sizeof(struct student));
    assert (s != 0);

     /*return the pointer*/
     return s;
}

void generate(struct student* students){
     /*Generate random ID and scores for ten students, ID being between 1 and 10, scores between 0 and 100*/
   int i, j;
   int flag;
   int randNum = 0;
   for (i = 0; i < 10; i++) {
        flag = 1;
         do {
            randNum = (rand()%10 + 1);  //generate random ID for each student

            for (j = 0; j < 10 && flag == 1; j++) {  //search array for matching numbers
                if (students[j].id == randNum) {
                    flag = 0;
                }
                if (j == 9 && flag == 1) {
                    flag = 0;
                }
            }
         }
        while (flag == 1);  //set condition

        students[i].id = randNum;
        students[i].score = (rand()%(100 - 0 + 1) + 0);  //generate random score for each student
    }
}


void output(struct student* students){
     /*Output information about the ten students in the format:
              ID1 Score1
              ID2 score2
              ID3 score3
              ...
              ID10 score10*/
        int i;
        printf("Student scores: \n\n");
        for (i = 0; i < 10; i++) {
            printf("\t%d, %d\n", students[i].id, students[i].score);
        }
}

void summary(struct student* students){
     /*Compute and print the minimum, maximum and average scores of the ten students*/
    int sumS, minS, maxS, avgS, i, j, tempID, tempS;
    printf("Sorted students by scores: \n");
    for (i = 0; i < 10; i++) {
        sumS += students[i].score;
        for (j = 0; j <10; j++) {
            if (students[i].score < students[j].score) {
                tempS = students[j].score;
                tempID = students[j].id;
                students[j].score = students[i].score;
                students[j].id = students[i].id;
                students[i].score = tempS;
                students[i].id = tempID;
            }
        }
    }
    for (i = 0; i < 10; i++) {
        printf("\t%d, %d\n", students[i].id, students[i].score);
    }
    printf("Minimum score: %d\n", minS = students[0].score);
    printf("Maximum score: %d\n", maxS = students[9].score);
    printf("Average score: %d", avgS = sumS/10);
}

void deallocate(struct student* stud){
     /*Deallocate memory from stud*/
     free(stud);
}

int main(){
    struct student* stud = NULL;

    /*call allocate*/
    stud = allocate();

    /*call generate*/
    generate(stud);

    /*call output*/
    output(stud);

    /*call summary*/
    summary(stud);

    /*call deallocate*/
    deallocate(stud);

    return 0;
}
Was it helpful?

Solution

You set the flag to 0 if the number already was chosen, so you should test while(flag == 0), and re-set the flag to 1 at the start of the loop:

do {
    flag = 1;
    randNum = (rand()%10 + 1);  //generate random ID for each student

    for (j = 0; j < i && flag == 1; j++) {  //search array for matching numbers
        if (students[j].id == randNum) {
            flag = 0;
        }
    }
}
while (flag == 0);  //set condition

Now, flag == 0 means "already seen, try again" and flag == 1 means "it's a new number, go ahead and write it to the array".

Also, you only have the array slots for indices < i filled, so the comparison loop should not go to 9, but only to i-1.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top