C - удалить учеников из массива (массива структуры), кроме 10 с самым высоким средним баллом - PullRequest
2 голосов
/ 16 февраля 2020

Привет всем и спасибо, что нашли время, чтобы прочитать это. Я занимаюсь C и натолкнулся на упражнение, которое не мог решить в течение нескольких дней, независимо от того, что я делаю.

В упражнении говорится, что мне дано две структуры Student и Grade. Я должен создать функцию, которая принимает массив учеников в качестве параметра и удаляет всех учеников, кроме 10 с самым высоким средним баллом . Есть два ограничения: Я не могу создавать массивы и не могу отсортировать данный массив.

Что я пробовал : я создал для l oop итерация от 0 до size-10 и удаление учеников одного за другим, начиная с ученика с наименьшей средней оценкой, так что в итоге у меня остается 10 с самым высоким средняя оценка.

У меня есть вспомогательные функции: средняя вычисляет среднюю оценку одного ученика;

index_lowest находит индекс ученика равным удалено

функция top_students - это основная функция, которая выполняет то, что говорит упражнение.

Вот моя программа:

struct Grade {
    char subject_name[100];
    int grade;
};

struct Student {
    char name[20], surname[20];
    int no_of_grades;
    struct Grade grades[100];
};

double average(struct Student s) {
    int i;
    double avg = 0;
    for (i = 0; i < s.no_of_grades; i++) {
        avg += s.grades[i].grade;
    }
    return avg / s.no_of_grades;
}

int index_lowest(struct Student students[], int size) { // returns the index of the student with the lowest avg
    double min = average(students[0]);

    int i, mini = 0; // mini is the index we search for

    for (i = 0; i < size; i++) {
        if (average(students[i]) < min) {
            min = average(students[i]);
            mini = i;
        }
    }
    return mini;
}

void top_students(struct Student students[], int size) {
    int i, j;

    for (i = 0; i < (size - 10); i++) {
        int index = index_lowest(students, size);

        for (j = index; j < (size - 1); j++) {
            students[j] = students[j + 1];
        }
        size--;
    }
}

1 Ответ

3 голосов
/ 16 февраля 2020

Проверка внешнего l oop из top_student неверна: вы увеличиваете i и уменьшаете size на каждой итерации, поэтому вы останавливаетесь слишком рано.

Вот упрощенная версия:

void top_students(struct Student students[], int size) {
    while (size > 10) {
        for (int j = index_lowest(students, size); j < size - 1; j++) {
            students[j] = students[j + 1];
        }
        size--;
    }
}

Обратите внимание, что передача больших структур по значению неэффективна. Передача указателя намного предпочтительнее. Также рекомендуется вычислять average() только один раз за итерацию.

Вот модифицированная версия:

double average(const struct Student *s) {
    int i, n;
    double avg = 0.0;
    for (i = 0, n = s->no_of_grades; i < n; i++) {
        avg += s->grades[i].grade;
    }
    return avg / n;
}

int index_lowest(const struct Student students[], int size) {
    // returns the index of the student with the lowest avegare
    // in case of ties, return the last index for the lowest average
    double min = average(&students[0]);
    int i, mini = 0; // mini is the index we search for

    for (i = 1; i < size; i++) {
        double avg = average(&students[i]);
        if (avg <= min) {
            min = avg;
            mini = i;
        }
    }
    return mini;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...