数据结构实验课布置了一个线性表的作业,网上查了查发现很少用stl实现的,于是自己写了一个,以此文用来记录。
(其实是国庆太无聊了想水一下更新)
编写一个实验程序实现以下功能:
有一个学生成绩文本文件xyz4.in,第一行为整数n,接下来为n行学生基本信息,包括学号、姓名和班号,接下来为整数m,然后为m行课程信息,包括课程编号和课程名,再接下来为整数k,然后为k行学生成绩,包括学号、课程编号和分数。
编写一个程序按班号递增排序输出所有学生的成绩,相同班号按学号递增排序,同一个学生按课程编号递增排序,相邻的班号和学生信息不重复输出。
阅读实验要求后,可以将我们需要完成的事划分成以下几个部分
从实验要求可得我们并不需要后续的交互,大大降低了作业的难度,因此手写和使用stl区别并不大,手写线性表的文章有很多,这里采用stl。
然后开始选择容器,因为是线性表,自然选择顺序容器,有vector,list,deque等容器,因为不需要后续的插入与删除操作,故选择vector。
我这里选择的是结构体,显然需要学生与课程两个结构体。
实验要求说明需要读入文本文件来进行操作,所以需要在正常的程序上稍作修改。
有很多写的很好也很详细的文章了,这里推荐几篇。
vector操作
vector函数及其实现
C++读取文本文件的几种方法
懒得看的直接跳到下面的源代码吧(
#include //io流输入输出
#include //setw场宽函数
#include //vector容器
#include // sort排序函数
#include //读文件
这个没啥好说的
struct Course
{
string id; //课程编号
string name; //课程名
string price; //成绩
};
struct Student
{
string id; //学号
string name; //姓名
string classNum; //班号
vector<Course> price; //成绩
};
vector<Student> studentList;
vector<Course> courseList;
三个辅助排序函数,懒得想命名了,看注释吧
bool cmp0(Student a, Student b)
{
return a.id < b.id; //学号升序排列
}
bool cmp1(Student a, Student b)
{
if (a.classNum != b.classNum)
return a.classNum < b.classNum; //如果班号不同则返回班号小的
else
return a.id < b.id; //否则返回学号小的
}
bool cmp2(Course a, Course b)
{
return a.id < b.id; //课程编号升序排列
}
个人习惯先正常输入,全部写完后再改为ifstream读文件。这里加了一些反馈文字方便理解。
puts(" 欢迎进入学生管理系统 ");
int n; //学生人数
cout << "请初始化学生信息,输入学生数量:";
cin >> n;
puts("开始初始化学生信息");
while (n--) //初始化学生信息
{
Student student;
cout << "输入新学生信息" << endl;
cout << "请输入学号:";
cin >> student.id;
cout << "请输入姓名:";
cin >> student.name;
cout << "请输入班号:";
cin >> student.classNum;
cout << "该学生信息录入完成" << endl;
studentList.push_back(student);
}
cout << "学生信息已完全录入";
sort(studentList.begin(), studentList.end(), cmp0);
// 这个函数会影响到接下来能否正确输入学生成绩
int m; //课程数量
cout << "请初始化课程信息,输入课程数量:";
cin >> m;
puts("开始初始化课程信息");
while (m--) //初始化课程信息
{
Course course;
cout << "输入新课程信息" << endl;
cout << "请输入课程编号:";
cin >> course.id;
cout << "请输入课程名:";
cin >> course.name;
cout << "该课程信息录入完成" << endl;
courseList.push_back(course);
}
cout << "课程信息已完全录入";
sort(courseList.begin(), courseList.end(), cmp2);
//课程排序,方便升序输出
int k; //学生成绩数量 其实可以直接用n*m计算
cin >> k;
while (k--)
{
Course course;
int studentId;
fin >> studentId >> course.id >> course.price; //学号、课程编号、成绩
studentList[studentId - 1].price.push_back(course); //别忘了索引值是从0开始的
}
for (auto x : studentList)
sort(x.price.begin(), x.price.end(), cmp2); //每个学生的成绩按课程编号升序排好
sort(studentList.begin(), studentList.end(), cmp1);//重新按班号排序学生
用了一些函数和小技巧来让输出结果对齐以及变得更美观,不用也无伤大雅。
string tag = "";
for (auto x : studentList)
{
if (x.classNum != tag)
{
cout << "===============班号:" << x.classNum << "===============" << endl;
tag = x.classNum;
}
cout << x.id << " " << x.name << " ";
for (int i = 0; i < courseList.size(); i++)
{
cout << setiosflags(ios::left) << setw(10) << courseList[i].name;
cout << setiosflags(ios::right) << setw(30) << x.price[i].price << endl;
}
cout << endl;
}
cout << "退出成功,欢迎下次使用!" << endl;
return 0;
#include //io流输入输出
#include //setw场宽函数
#include //vector容器
#include // sort排序函数
#include //读文件
using namespace std;
struct Course
{
string id; //课程编号
string name; //课程名
string price; //成绩
};
struct Student
{
string id; //学号
string name; //姓名
string classNum; //班号
vector<Course> price; //成绩
};
vector<Student> studentList;
vector<Course> courseList;
bool cmp0(Student a, Student b)
{
return a.id < b.id; //学号升序排列
}
bool cmp1(Student a, Student b)
{
if (a.classNum != b.classNum)
return a.classNum < b.classNum; //如果班号不同则返回班号小的
else
return a.id < b.id; //否则返回学号小的
}
bool cmp2(Course a, Course b)
{
return a.id < b.id; //课程编号升序排列
}
int main()
{
ifstream fin;
fin.open("xyz4.in", ios::in);
if (!fin.is_open())
{
cout << "无法找到这个文件!" << endl;
return 0;
}
puts(" 欢迎进入学生管理系统 ");
int n; //学生人数
fin >> n;
while (n--) //初始化学生信息
{
Student student;
fin >> student.id;
fin >> student.name;
fin >> student.classNum;
studentList.push_back(student);
}
sort(studentList.begin(), studentList.end(), cmp0); // 这个函数会影响到接下来能否正确输入学生成绩
int m; //课程数量
fin >> m;
while (m--) //初始化课程信息
{
Course course;
fin >> course.id;
fin >> course.name;
courseList.push_back(course);
}
sort(courseList.begin(), courseList.end(), cmp2); //课程排序,方便升序输出
int k; //学生成绩数量 其实可以直接用n*m计算
fin >> k;
while (k--)
{
Course course;
int studentId;
fin >> studentId >> course.id >> course.price; //学号、课程编号、成绩
studentList[studentId - 1].price.push_back(course); //别忘了索引值是从0开始的
}
for (auto x : studentList)
sort(x.price.begin(), x.price.end(), cmp2); //每个学生的成绩按课程编号升序排好
sort(studentList.begin(), studentList.end(), cmp1); //重新按班号排序学生
string tag = "";
for (auto x : studentList)
{
if (x.classNum != tag)
{
cout << "===============班号:" << x.classNum << "===============" << endl;
tag = x.classNum;
}
cout << x.id << " " << x.name << " " << endl;
for (int i = 0; i < courseList.size(); i++)
{
cout << courseList[i].name;
cout << setiosflags(ios::right) << setw(20 - courseList[i].name.size()) << x.price[i].price << endl;
}
cout << endl;
}
cout << "退出成功,欢迎下次使用!" << endl;
fin.close();
return 0;
}
水了一篇文章美滋滋
完结撒花✿✿ヽ(°▽°)ノ✿✿自认为已经写的很详细了,因为没有后续的插入与删除操作,所以文章确实也很水,希望能有所帮助。