首页 > 解决方案 > C - 从数组(结构数组)中删除学生,但平均成绩最高的 10 人除外

问题描述

大家好,感谢您花时间阅读本文。我正在练习 C,并且遇到了一个练习,无论我做什么,我都无法解决好几天。

练习说我有两个结构StudentGrade. 我要创建一个函数,该函数接受一组学生作为参数,并删除除 10 名平均成绩最高的学生以外的所有学生。有两个限制:我不能创建任何数组,也不能对给定的数组进行排序。

我尝试了什么:我创建了一个从0size-10迭代的 for 循环,并从平均成绩最低的学生开始逐个删除学生,所以最后,我剩下 10 个平均成绩最高的学生年级。

我有辅助功能:average计算一个学生的平均成绩;

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

标签: carraysdata-structures

解决方案


外部循环的测试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;
}

推荐阅读