ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

智能成绩表(C语言)

2026/9/21 9:27:53 拓冰建站 浏览量
智能成绩表(C语言)

题目描述

小明来到某学校当老师,需要将学生按考试总分或单科分数进行排名,你能帮帮他吗?

输入描述

第 1 行输入两个整数,学生人数 n 和科目数量 m,0<n<100,0<m < 10
第 2 行输入 m 个科目名称,彼此之间用空格隔开。

  • 科目名称只由英文字母构成,单个长度不超过 10 个字符。
  • 科目的出现顺序和后续输入的学生成绩一一对应
  • 不会出现重复的科目名称

第 3 行开始的 n 行,每行包含一个学生的姓名和该生 m 个科目的成绩 (空格隔开)。

  • 学生不会重名
  • 学生姓名只由英文字母构成,长度不超过 10 个字符
  • 成绩是 0~100 的整数,依次对应第 2 行输入的科目

第 n+2 行,输入用作排名的科目名称。若科目不存在,则按总分进行排序。

输出描述

输出一行,按成绩排序后的学生名字,空格隔开。成绩相同的按照学生姓名字典顺序排序。

示例一

输入

3 2
yuwen shuxue
fangfang 95 90
xiaohua 88 95
minmin 100 82
shuxue

输出

xiaohua fangfang minmin

说明

按 shuxue 成绩排名,依次是 xiaohua、fangfang、minmin

思路

  1. 数据输入与初始化

    • 首先读取学生人数 n 和科目数量 m
    • 接着,读取并存储 m 个科目名称到二维数组 subject 中。
    • 初始化一个大小为 n 的结构体数组 stu,用于存放每个学生的姓名、各科成绩以及排序的关键字段(key)。
    • 然后逐行读取每个学生的姓名和对应科目的成绩,并存入 stu 数组中。
  2. 确定排序依据

    • 输入要进行排名的科目名称 sub
    • 遍历科目列表,查找是否存在该科目。若存在,则将该科目的成绩作为排序依据,赋值给每个学生的 key 字段。
    • 若未找到指定科目,则计算每个学生的总分,并用总分作为排序依据。
  3. 排序

    • 使用 C 标准库中的 qsort 函数对 stu 数组中的学生按照 key 字段进行降序排列。这里定义了一个比较函数 cmp,当 key 不同时按 key 值排序,相同则按照学生姓名字典顺序升序排序。
  4. 输出结果

    • 对排序后的 stu 数组,遍历并打印出所有学生的姓名,以空格隔开。

总结来说,通过接收用户输入的学生信息和排序要求,首先完成数据结构的构建和填充,然后根据题目需求选择合适的排序依据,最后利用快速排序算法实现对学生列表的排序,并按照题目要求的格式输出排名结果。

代码

无注释

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {char name[10];int scores[10];int key; // 用于排序的依据
} Students;int cmp(const void *a, const void *b) {Students *s1 = (Students *)a;Students *s2 = (Students *)b;if (s1->key != s2->key) {return s2->key - s1->key; // 降序}return strcmp(s1->name, s2->name);
}
int main() {int n, m;scanf("%d %d", &n, &m);char subject[m][11];for (int i = 0; i < m; i++) {scanf("%s", subject[i]);}Students stu[n];for (int i = 0; i < n; i++) {scanf("%s", stu[i].name);for (int j = 0; j < m; j++) {scanf("%d", &stu[i].scores[j]);}}char sub[11];scanf("%s", sub);int found = 0;for (int k = 0; k < m; k++) {if (strcmp(subject[k], sub) == 0) {found = 1;for (int i = 0; i < n; i++) {stu[i].key = stu[i].scores[k];}break;}}if (found == 0) {for (int i = 0; i < n; i++) {stu[i].key = 0;for (int j = 0; j < m; j++) {stu[i].key += stu[i].scores[j];}}}qsort(stu, n, sizeof(Students), cmp);for (int i = 0; i < n; i++) {printf("%s ", stu[i].name);}printf("\n");return 0;
}

有注释

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 定义学生结构体,包含姓名、各科成绩以及用于排序的关键字段(key)
typedef struct {char name[10];  // 存储学生姓名int scores[10]; // 存储每个学生的各科成绩int key; // 用于根据指定科目成绩或总分进行排序的依据
} Students;// 定义比较函数,用于qsort排序。a和b是需要比较的两个学生结构体指针
int cmp(const void *a, const void *b) {Students *s1 = (Students *)a;Students *s2 = (Students *)b;// 比较key字段,按照降序排列if (s1->key != s2->key) {return s2->key - s1->key;}// 若key相同,则按照学生姓名字典顺序升序排列return strcmp(s1->name, s2->name);
}int main() {int n, m;               // 分别存储学生人数和科目数量scanf("%d %d", &n, &m); // 输入学生人数和科目数量// 存储科目名称的二维数组char subject[m][11];for (int i = 0; i < m; i++) {scanf("%s", subject[i]); // 读取每门科目的名称}// 初始化学生数组Students stu[n];// 读取每个学生的姓名和各科成绩for (int i = 0; i < n; i++) {scanf("%s", stu[i].name); // 读取学生姓名for (int j = 0; j < m; j++) {scanf("%d", &stu[i].scores[j]); // 读取单科成绩}}// 读取用于排名的科目名称char sub[11];scanf("%s", sub);int found = 0; // 标记是否找到用于排序的科目for (int k = 0; k < m; k++) {if (strcmp(subject[k], sub) == 0) { // 如果输入的科目存在于科目列表中found = 1;// 将对应科目的成绩作为排序依据赋值给每个学生的key字段for (int i = 0; i < n; i++) {stu[i].key = stu[i].scores[k];}break;}}// 如果未找到指定科目,则以总分为排序依据if (found == 0) {for (int i = 0; i < n; i++) {stu[i].key = 0; // 初始化总分为0// 计算每个学生的总分,并赋值给key字段for (int j = 0; j < m; j++) {stu[i].key += stu[i].scores[j];}}}// 使用qsort对整个学生数组进行排序qsort(stu, n, sizeof(Students), cmp);// 输出排序后的学生姓名列表for (int i = 0; i < n; i++) {printf("%s ", stu[i].name);}printf("\n"); // 输出换行符以结束输出return 0; // 程序正常结束
}