一、功能简介
本程序是在前面代码基础上的修改与优化,同样是一个简单的学生成绩管理系统。功能包括录入学生成绩、输出学生成绩、查询某个学生的成绩、按总分排序等,具体如下:
1.登录:输入密码进行登录,最多允许3次密码错误。
2.录入:输入学生人数n,然后输入每个学生的姓名和每门课程成绩,并将这些成绩添加到该学生的scores变量中。
3.输出:输出所有学生的成绩。首先输出首行姓名和课程名称,然后输出每个学生的姓名和其对应成绩。
4.查询:输入要查询的学生姓名,并在names变量中查找该姓名。如果找到了该姓名,则输出该学生的姓名和对应的成绩;否则输出“未找到该学生”。
5.排序:按照学生的总分对学生进行排序。首先计算每个学生的总分,将学生姓名和对应的总分存储在一个vector中,然后对该vector进行排序,最后输出排序后的学生姓名和总分。
本代码的改进之处主要是引入容器<vector>,其中,成绩是以二维vector的形式存储的,学生的姓名是以vector<string>的形式存储的,课程名是以vector<string>的形式存储的,总分是以vector<pair<string, int>>的形式存储的,代码中适时运用了相关的成员函数,例如push_back()、pop_back()、size()等。
再有,代码对上一份作业的一些逻辑也做出了修改,例如查找是输入学生姓名,输出其所有成绩,而不是输入姓名和成绩查找其科目是什么,我觉得改进之后更为合理,但是由于前面也是我的思考,所以不再修改上一份作业的代码,毕竟也是能说得通的。另外,主函数出增加了默认的“无效的选择,请重新输入!”,可以防止输出时候越界。还修改了一些小细节,但是大体思路没有变化。当然程序没有完全使用给出的后缀代码,因为我感觉我这个更简单易懂点,但是修改也不是很大。
二、源代码实现
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Score {
vector<vector<int>> scores; //存储成绩
vector<string> names; // 存储学生姓名
vector<string> courses = {"python", "c++", "linux", "java", "php"};; // 存储课程名
public:
int login();//登录
void inputScore();//输入
void outputScore();//输出
void queryScore() ;//查找
int getIndex(const string& name) const;//获取下标
void sortScore();//排序
};
//显示菜单
void displayMenu() {
cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
cout << "+ 学生成绩管理系统 +\n";
cout << "+ +\n";
cout << "+ 1. 录入 +\n";
cout << "+ 2. 输出 +\n";
cout << "+ 3. 查询 +\n";
cout << "+ 4. 排序 +\n";
cout << "+ 5. 结束 +\n";
cout << "+ +\n";
cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
}
/*登录系统,输入密码并检查密码是否正确。
如果密码错误,则会允许用户再次尝试,最多3次。
如果密码正确,返回值为1;
否则返回值为0。*/
int Score::login() {
string password;
static const string key = "1234";
int count = 0;
int s = 0;
do {
count++;
cout << "请输入口令:";
getline(cin, password);
if (password == key)
s = 1;
else
s = 0;
} while (s == 0 && count < 3);
return s;
}
/*输入学生的成绩。
首先输入学生人数n。
然后对于每个学生,输入姓名,并将其添加到names变量中。
接着,输入该学生每门课程的成绩,并将这些成绩添加到该学生的scores变量中。*/
void Score::inputScore() {
int n;
cout << "请输入学生人数:";
cin >> n;
cin.ignore(); // 换行
for (int i = 0; i < n; i++) {
string name;
cout << "请输入第" << i + 1 << "个学生的姓名:";
getline(cin, name);
names.push_back(name);
vector<int> student_scores;
for (int j = 0; j < courses.size(); j++) {
int score;
cout << "请输入" << name << "的" << courses[j] << "成绩:";
cin >> score;
student_scores.push_back(score);
}
scores.push_back(student_scores);
cin.ignore(); //换行
}
}
/*输出所有学生的成绩.
首先首行输出姓名和课程名称,
然后对于每个学生,输出姓名和其对应的成绩。*/
void Score::outputScore() {
cout << "姓名\t";//首行标题
for (const auto& course : courses) {
cout << course << "\t";
}
cout << endl;
for (int i = 0; i < names.size(); i++) {//后续
cout << names[i] << "\t";
for (int j = 0; j < courses.size(); j++) {
cout << scores[i][j] << "\t";
}
cout << endl;
}
}
/*查询某个学生的成绩。
输入要查询的学生姓名,并在names变量中查找该姓名。
如果找到了该姓名,则输出该学生的姓名和对应的成绩;(类似输出代码)
否则输出“未找到该学生”。*/
void Score::queryScore() {
string name;
cout << "请输入要查询的学生姓名:";
getline(cin, name);
auto it = find(names.begin(), names.end(), name);
if (it == names.end()) {
cout << "未找到该学生" << endl;
} else {
int index = it - names.begin();
cout << "姓名\t";//表头
for (const auto& course : courses) {
cout << course << "\t";
}
cout << endl;
cout << names[index] << "\t";//后续
for (int j = 0; j < courses.size(); j++) {
cout << scores[index][j] << "\t";
}
cout << endl;
}
}
//获取下标
int Score::getIndex(const string& name) const {
auto it = find(names.begin(), names.end(), name);
if (it == names.end()) {
return -1; // 没有找到
}
return it - names.begin();
}
/*按照学生的总分对学生进行排序。
首先计算每个学生的总分,
将学生姓名和对应的总分存储在一个vector<pair<string, int>>类型的变量total_scores中。
然后使用sort()函数对total_scores变量进行排序,
按照总分从高到低输出每个学生的姓名、总分以各科分数。*/
void Score::sortScore() {
vector<pair<string, int>> total_scores;
for (int i = 0; i < names.size(); i++) {//遍历每个学生
int total = 0;//总成绩
for (int j = 0; j < courses.size(); j++) {//遍历每个课程
total += scores[i][j];//得到总成绩
}
total_scores.push_back(make_pair(names[i], total));//将每个学生的名字和总成绩组成一个 pair,存入total_scores
}
sort(total_scores.begin(), total_scores.end(), [](const auto & a, const auto & b) {//此处运用的是一个 lambda 表达式
return a.second > b.second;//按照总成绩进行比较,即 pair 的第二个元素
});
cout << "下面是按照总分排序的结果:" << endl;
cout << "姓名\t总分\t" ;//首行
for (const auto& course : courses) {
cout << course << "\t";
}
cout << endl;
for (const auto& [name, total] : total_scores) {
cout << name << "\t" << total << "\t";
for (int j = 0; j < courses.size(); j++) {
cout << scores[getIndex(name)][j] << "\t";
}
cout << endl;
}
}
int main() {
Score;
if (score.login()) {
int choice;
while (1) {
displayMenu();
cout << "请输入您的选择:";
cin >> choice;
cin.ignore(); // 换行
switch (choice) {
case 1:
score.inputScore();
break;
case 2:
score.outputScore();
break;
case 3:
score.queryScore();
break;
case 4:
score.sortScore();
break;
case 5:
cout << "谢谢使用!" << endl;
exit(0);
break;
default:
cout << "无效的选择,请重新输入!" << endl;
break;
}
}
}
return 0;
}
三、运行结果