Выполнить цикл для создания массива уникального случайного массива

Я написал код для создания массива структур. Переменная id должна быть уникальной и генерироваться случайным образом. Однако, похоже, происходит следующее: если функция generate (которая генерирует и заполняет массив структур) встречает совпадающее число в массиве, для переменной флага устанавливается значение 0, и она выходит из цикла do без создания нового случайного числа. перепроверить совпадение. Затем, когда цикл завершается, код продолжает работу и все равно присваивает совпадающее случайное число пустому месту в массиве. В качестве предостережения я понимаю, что было бы проще просто взять все 10 возможных целых чисел, переместить их и заполнить массив, но я пытаюсь освоить rand(), используя небольшой образец, чтобы я мог посмотреть, что это такое делаю в отладчике. Я подозреваю, что просто слишком долго смотрел на это и слишком много пробовал, но любые предложения будут оценены. Спасибо.

РЕДАКТИРОВАТЬ: Просто чтобы уточнить мой вопрос, конкретно касается цикла do и того, что мне нужно сделать, чтобы убедиться, что при обнаружении совпадения программа генерирует новое случайное число и снова начинает поиск совпадения. Это следует повторять для каждой позиции в массиве, пока каждый элемент идентификатора не станет уникальным. В настоящее время, когда я запускаю программу, я все еще получаю повторяющиеся числа.

#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;
}

person user1852050    schedule 13.01.2013    source источник


Ответы (1)


Вы устанавливаете флаг на 0, если число уже было выбрано, поэтому вы должны проверить while(flag == 0) и переустановить флаг на 1 в начале цикла:

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

Теперь flag == 0 означает «уже видел, попробуйте еще раз», а flag == 1 означает «это новый номер, продолжайте и запишите его в массив».

Кроме того, у вас заполнены только слоты массива для индексов < i, поэтому цикл сравнения должен идти не к 9, а только к i-1.

person Daniel Fischer    schedule 13.01.2013
comment
Я попробовал ваше решение по перемещению флага оператора = 1; в скобках цикла do и изменив условие на flag == 0, но в результате получился бесконечный цикл. - person user1852050; 13.01.2013
comment
@user1852050 user1852050 Сначала я забыл удалить неправильную настройку от flag до 0, когда было достигнуто 9. Это исправлено, попробуйте еще раз. - person Daniel Fischer; 13.01.2013