数据结构 线性表实验(stl vector实现)

文章目录

  • 写作背景
  • 一、实验介绍
    • 1.1 实验要求
    • 1.2 分析
      • (1)选择合适的数据结构
      • (2)建立结构体或类,方便储存
      • (3)文件的基本操作
  • 二、前置知识
      • vector
      • 读入文件
  • 三.代码分析
    • 定义
      • 头文件
      • 结构体
      • 容器
    • 自定义函数
    • 主函数
      • 输入
        • 学生
        • 课程
        • 学生成绩
      • 后续处理
      • 输出
  • 四.源代码
  • 总结


写作背景

数据结构实验课布置了一个线性表的作业,网上查了查发现很少用stl实现的,于是自己写了一个,以此文用来记录。
(其实是国庆太无聊了想水一下更新)


一、实验介绍

1.1 实验要求

编写一个实验程序实现以下功能:
有一个学生成绩文本文件xyz4.in,第一行为整数n,接下来为n行学生基本信息,包括学号、姓名和班号,接下来为整数m,然后为m行课程信息,包括课程编号和课程名,再接下来为整数k,然后为k行学生成绩,包括学号、课程编号和分数。

编写一个程序按班号递增排序输出所有学生的成绩,相同班号按学号递增排序,同一个学生按课程编号递增排序,相邻的班号和学生信息不重复输出。


1.2 分析

阅读实验要求后,可以将我们需要完成的事划分成以下几个部分

(1)选择合适的数据结构

从实验要求可得我们并不需要后续的交互,大大降低了作业的难度,因此手写和使用stl区别并不大,手写线性表的文章有很多,这里采用stl。
然后开始选择容器,因为是线性表,自然选择顺序容器,有vector,list,deque等容器,因为不需要后续的插入与删除操作,故选择vector。

(2)建立结构体或类,方便储存

我这里选择的是结构体,显然需要学生与课程两个结构体。

(3)文件的基本操作

实验要求说明需要读入文本文件来进行操作,所以需要在正常的程序上稍作修改。


二、前置知识

有很多写的很好也很详细的文章了,这里推荐几篇。

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

总结

水了一篇文章美滋滋
完结撒花✿✿ヽ(°▽°)ノ✿✿自认为已经写的很详细了,因为没有后续的插入与删除操作,所以文章确实也很水,希望能有所帮助。

你可能感兴趣的:(c++,数据结构,c语言)