第四十天:成绩排序
成绩排序
一、问题
首行是学生数量 n
,取值范围在 0
到 20
之间。随后的 n
行,每行都记录着一个学生的名字和成绩,两者由单个空格分隔。学生名字仅包含字母,长度不超过 20
,成绩则是不大于 100
的非负整数。我们的目标清晰明确:按照指定规则对这些成绩数据进行排序,并将排序后的结果按每行一个学生的名字和成绩(中间隔一个空格)的格式输出。
二、C++ 实现思路
为了解决这个问题,我们可以充分利用 C++ 标准库提供的强大功能。以下是详细的实现方案:
-
数据结构定义:
首先,我们定义一个Student
结构体来存储学生信息:struct Student {string name; // 学生姓名double score; // 考试成绩 };
这个结构体清晰地组织了两个相关联的数据项,便于后续处理。
-
自定义比较函数:
为了实现按成绩从高到低排序,我们需要编写一个比较函数:bool compareStudents(const Student &a, const Student &b) {return a.score > b.score; // 降序排列 }
这个函数将被用作排序的标准,通过返回布尔值来指示两个元素的相对顺序。
-
排序实现:
使用标准库的sort
算法进行排序:vector<Student> students; // 假设已填充数据 sort(students.begin(), students.end(), compareStudents);
这里需要注意的是:
sort
算法的时间复杂度为 O(N log N)- 该算法使用了快速排序的变体,对小数据集特别高效
-
结果输出:
最后,遍历已排序的容器并输出结果:for(const auto &student : students) {cout << student.name << ": " << student.score << endl; }
应用场景示例:
假设我们需要处理一个班级50名学生的期末考试成绩,这套方案可以:
- 高效地完成排序
- 方便后续进行成绩分析
- 支持快速查找特定排名区间的学生
扩展考虑:
在实际应用中,可以进一步:
- 添加异常处理(如成绩为负数的情况)
- 支持多种排序方式(如按姓名升序)
- 将结果输出到文件便于长期保存为了解决这个问题,我们可以借助 C++ 的一些强大特性。首先,定义一个结构体来存储学生的名字和成绩,方便数据管理。然后,编写一个比较函数,用于定义排序规则。最后,利用标准库中的排序函数对数据进行排序,并输出结果。
三、C++ 代码实现
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>using namespace std;// 定义学生结构体
struct Student {string name;int score;
};// 比较函数,用于排序
bool compare(Student a, Student b) {if (a.score != b.score) {return a.score > b.score;} else {return a.name < b.name;}
}int main() {int n;cin >> n;vector<Student> students(n);for (int i = 0; i < n; ++i) {cin >> students[i].name >> students[i].score;}sort(students.begin(), students.end(), compare);for (const auto& student : students) {cout << student.name << " " << student.score << endl;}return 0;
}
四、代码解读
-
定义学生结构体:
struct Student
定义了一个名为Student
的结构体,它包含两个成员变量。string name
用于存储学生的名字,int score
用于存储学生的成绩。结构体为我们提供了一种将相关数据组织在一起的便捷方式,使代码更具结构性和可读性。在这个场景中,每个Student
对象都代表了一名学生的成绩信息。
-
编写比较函数:
compare
函数是排序的核心逻辑所在。它接受两个Student
类型的参数a
和b
。- 首先检查两个学生的成绩是否不同。如果
a.score != b.score
,则通过return a.score > b.score;
来确保成绩高的学生排在前面,实现成绩从高到低的排序。 - 当成绩相同时,即
a.score == b.score
,此时通过return a.name < b.name;
来比较名字的字典序,保证名字字典序小的学生排在前面。这种双重判断机制完全符合题目的排序要求。
-
主函数中的输入部分:
int n; cin >> n;
从输入中读取学生的数量n
。vector<Student> students(n);
创建一个大小为n
的Student
类型向量students
,用于存储所有学生的信息。向量是 C++ 中一种动态数组,它能根据需要自动调整大小,非常适合存储不确定数量的数据。- 通过
for
循环for (int i = 0; i < n; ++i)
,依次读取每个学生的名字和成绩。cin >> students[i].name >> students[i].score;
按照输入格式将数据存储到students
向量的对应位置。cin
是 C++ 标准输入流,它能方便地从控制台读取不同类型的数据。
-
主函数中的排序与输出部分:
sort(students.begin(), students.end(), compare);
使用 C++ 标准库中的sort
函数对students
向量进行排序。sort
函数的第一个参数students.begin()
是排序范围的起始迭代器,第二个参数students.end()
是排序范围的结束迭代器(不包含该位置的元素),第三个参数compare
是我们自定义的比较函数,它决定了排序的具体规则。通过这一行代码,students
向量中的学生信息就会按照我们期望的规则进行排序。- 最后,通过范围 - for 循环
for (const auto& student : students)
遍历排序后的students
向量。cout << student.name << " " << student.score << endl;
将每个学生的名字和成绩按要求的格式输出到控制台,每行一个学生的信息。cout
是 C++ 标准输出流,用于将数据输出到屏幕。
五、样例分析
以输入样例:
4
Kitty 80
Hanmeimei 90
Joey 92
Tim 28
程序首先读取到学生数量 n = 4
,然后依次将 Kitty 80
、Hanmeimei 90
、Joey 92
和 Tim 28
存储到 students
向量中。接着,sort
函数依据 compare
函数的规则对向量进行排序。由于 Joey
的成绩 92
最高,所以排在第一位;接着是 Hanmeimei
,成绩为 90
;然后是 Kitty
,成绩 80
;最后是 Tim
,成绩 28
。最终输出的结果与输出样例一致:
Joey 92
Hanmeimei 90
Kitty 80
Tim 28