数据结构课设-考试报名管理系统
目录
一、需求分析及测试数据
1.需求分析
考试报名系统是一个学校不可缺少的部分,它对于学校的管理者和学生来说都至关重要,所以一个良好的考试报名系统应该能够为用户提供充足的信息和功能。考试报名系统对于学校加强考试管理有极其重要的作用。随着学生数量和考试数量的日益庞大,如何管理如此庞大的数据显得极为复杂,传统的手工管理工作量大且容易出错。随着计算机科学技术的不断成熟,使用计算机对考试报名系统进行管理,具有手工管理所无法比拟的优势。这些优点能够极大地提高学校和学生的效率,也是学校走向信息化、科学化、国际化的重要条件。因此,开发一套考试报名系统具有十分重要的意义。
2.测试数据
stu1 女 20 软件设计师
stu2 男 21 软件开发师
stu3 男 20 软件设计师
stu4 女 21 软件测试师。
二、概要设计及调用关系图
1.概要设计
系统设计
系统首先调用 StuSystem0函数实现对屏幕的初始化,完成对链表 list创建和输入数据工作,然后根据用户所输入的操作码(operatorCode) 执行链表 list 对应的成员函数
数据结构设计
该系统要求频繁的插入、删除、修改操作,而链表进行插入、删除等操作十分简便,因此考虑使用链表数据结构。同时,为了实现简易,在第一个结点之前附加一个头结点,并用头指针指向头结点,使得增加或者删除头结点与处理其他结点方法相同,使得程序简洁,更方便 单链表Q 的前插法的设计,也不需要将第一个和最后一个结点做特殊处理。
类结构设计
经典的链表一般包括两个 抽象数据类型Q (ADT) --链表结点类 (NODE) 与链表类(LinkList),而两个类之间的合关系可以采用获套、继承等多种关系。为方便处理,本系统将链表类(LinkList声明为链表结点类NODE)的友元,这样使得辩表结点类(LinkList)可以访问链表结点。同时将考生的信息封装到 Stu 结构体中,使得结点类的定义更简洁,更方便插入、删除、修改等功能.
2.调用关系图
三、关键代码
#include<iostream>
#include<string>
#include<windows.h>
using namespace std;
template<class T1,class T2>//类模板,只有两种类型的string和int类型,设置一个模板
class Student {
public:
void inputStudent(Student* head); //输入学生的信息
void outputStudent(Student * head); //输出学生的信息
void deleteStudent(Student * head); //删除学生的信息
void addStudent(Student * head); //添加学生的信息
void changeStudent(Student * head); //修改学生的信息
void findStudent(Student * head); //查找学生的信息
void getcountStudent(Student* head);
private:
T2 m_id; //考号
T1 m_name; //姓名
T1 m_sex; //性别
T2 m_age; //年龄
T1 m_type; //报考类型
Student<T1,T2>* next; //下一个节点的地址
};
int location;//设置一个全局变量,是学生的位置信息
//输入学生信息的函数
template<class T1, class T2>
void Student<T1,T2>::inputStudent(Student<T1,T2>* head)
{
Student* p1, * p2;
p1 = head;
tt:cout << "首先请建立考生信息系统!" << endl;
cout << "请输入考生人数:";
int n;
cin >> n;
if (n <= 0 || cin.fail()) // 输入错误的判定
{
cout << "输入错误,请重新输入"<<endl;// 输入错误的提示
if (cin.fail()) //如果输入的不是整数类型那么进行一个判断并且进行清空
{
cin.clear();
cin.ignore();
}
Sleep(1000);
system("cls");
goto tt;
}
cout << "请依次输入考生的考号,姓名,性别,年龄及报考类别!\n" ;
for (int i = 0; i < n; i++)
{
p2 = new Student; //建立一个新得节点
p1->next = p2; //头结点是空的
p1 = p1->next;
cin >> p1->m_id >> p1->m_name >> p1->m_sex >> p1->m_age >> p1->m_type; //依次进行输入的操作
}
p1->next = NULL; //最后的节点地址部分设为空
}
//输出考生信息的函数
template<class T1, class T2>
void Student<T1,T2>::outputStudent(Student<T1,T2>* head) {
Student* p1, * p2;
p1=head->next;
int r = 0;
cout << "考号\t姓名\t性别\t年龄\t报考类型" << endl;
while (p1!= NULL)
{
cout << p1->m_id<<"\t" << p1->m_name << "\t" << p1->m_sex << "\t" << p1->m_age << "\t" << p1->m_type << endl;
r++;
p1 = p1->next;
}
}
int amount= 0; //全局变量计算考生的个数
template<class T1, class T2>
void Student<T1,T2>::getcountStudent(Student<T1,T2>* head) {
Student* p1;
p1 = head->next;
while (p1 != NULL)
{
amount++; //每次进行一个自加,之所以用全局变脸是因为好输出,方便
p1 = p1->next;
}
}
template<class T1, class T2>
void Student<T1,T2>::addStudent(Student* head) //添加考生的函数
{
Student* p1, * p2; //设置两个指针节点,在这两个节点中间的位置加入元素
Student* p3;
cout << "请输入你要插入的考生的位置:";
cin >> location;
if (location > 0) //对考生的位置输入进行输入正误的判定
{
if (location > 0 && location <= amount )
{
p1 = head;
p2 = p1->next;
while (--location) //每次进行一个位置的自减
{
p2 = p2->next; //两个指针分别向后移动
p1 = p1->next;
}
p3 = new Student; //new一个新的节点
cout << "请依次输入考生的考号,姓名,性别,年龄及报考类别!\n";
cin >> p3->m_id >> p3->m_name >> p3->m_sex >> p3->m_age >> p3->m_type;//输入信息
p3->next = p2; //进行一个链接
p1->next = p3;
}
else //进行一个输入错误的判断
{
location = -1;
cout << "输入错误,请输入1到" << amount << "之间的数" << endl;
}
}
else
{
location = -1;
mm:cout << "输入错误,请输入1到" << amount << "之间的数" << endl;
if (cin.fail()) //这里如果输入的不是整型,比如输入的是字母就进行一个
{
cin.clear();
cin.ignore();
}
}
}
template<class T1, class T2>
void Student<T1,T2>::deleteStudent(Student<T1,T2>* head) //删除考生信息的函数
{
Student* p1, * p2; //删除的是p2指针
cout << "请输入你要删除考生的考号:";
p1 = head;
p2 = head->next;
cin >> location;
int i = amount;
if (location > 0) //输入考号
{
while (i)
{
if (p2->m_id==location)
{
cout<<"你删除的考生信息是:"<< p2->m_id << "\t" << p2->m_name << "\t" << p2->m_sex << "\t" << p2->m_age << "\t" << p2->m_type << endl;
p1->next = p2->next;
delete p2;
break;
}
p1 = p2;
p2 = p2->next;
i--;
if (i==0)//这里有bug
{
cout << "您删除的考生不存在"<<endl;
location = -1;
}
}
}
else
{
location = -1;
cout << "输入错误,请输入1到" << amount<< "之间的数" << endl;
if (cin.fail()) //这里如果输入的不是整型,比如输入的是字母就进行一个
{
cin.clear();
cin.ignore();
}
}
}
template<class T1, class T2>
void Student<T1,T2>::findStudent(Student* head) //查找考生的信息
{
Student* p1;
cout << "请输入您要查找考生的考号:";
cin >> location;
p1 = head->next;
//由于输入不同的错误进行相应的判定
if (location < 0) //小于0的判定
{
location = -1;
cout << "输入错误,请重新输入" << endl;
}
else if (cin.fail()) //输入的类型不同进行的判定
{
location = -1;
cout << "输入错误,请重新输入" << endl;
cin.clear();
cin.ignore();
}
else
{
while (p1 != NULL)
{
if (p1->m_id == location) //如果考号相等则输出查找学生的信息
{
cout << "考号\t姓名\t性别\t年龄\t报考类型" << endl;
cout << p1->m_id << "\t" << p1->m_name << "\t" << p1->m_sex << "\t" << p1->m_age << "\t" << p1->m_type << endl;
break;
}
p1 = p1->next;
if (p1 == NULL)
{
location = -1;
cout << "您查找的考生不存在"<<endl;
}
}
}
}
template<class T1, class T2>
void Student<T1,T2>::changeStudent(Student* head) //修改学生信息的函数
{
Student* p1; //只修改一个信息,所以设一个指针变量就行了
cout << "请输入要修改的考生的考号:";
cin >> location;
p1 = head->next;
//由于输入不同的错误进行相应的判定
if (location < 0) //小于0的判定
{
location = -1;
cout << "输入错误,请重新输入" << endl;
return;
}
if (cin.fail()) //输入的类型不同进行的判定
{
location = -1;
cout << "输入错误,请重新输入" << endl;
cin.clear();
cin.ignore();
return;
}
//如果输入正确,则进行以下的操作,
while (p1 != NULL) //先判断是不是一个空的链表
{
if (p1->m_id == location)
{
cout << "请输入您要修改的信息" << endl;
cin >> p1->m_id >> p1->m_name >> p1->m_sex >> p1->m_age >> p1->m_type;//输出
break;
}
p1 = p1->next; //指针向下一个移动
if (p1 == NULL)
{
location = -1;
cout << "您查找的考生不存在,请重新输入学号";
}
}
}
/*
1 stu1 男 21 游戏设计师
2 stu2 女 21 数据架构师
3 stu1 男 20 软件开发师
4 stu2 女 21 软件测试员
5 stu3 男 22 网络工程师
*/
int main() {
Student<string,int> h; //模板类变量的建立
Student<string,int>* head = new Student<string,int>; //设立一个头结点,并且在此项目中,头结点都是空的
h.inputStudent(head);
h.outputStudent(head);
h.getcountStudent(head);
while (true)
{
tt:cout << "请选择您要进行的操作(1为插入,2为删除,3为查找,4为修改,5为统计,0为取消操作)";
int n;
cin >> n;
switch (n)
{
case 1:
h.addStudent(head);
while (location == -1)
{
h.addStudent(head);
}
h.outputStudent(head);
h.getcountStudent(head);
break;
case 2:
h.deleteStudent(head);
while (location == -1)
{
h.deleteStudent(head);
}
h.outputStudent(head);
h.getcountStudent(head);
break;
case 3:
h.findStudent(head);
while (location == -1)
h.findStudent(head);
break;
case 4:
h.changeStudent(head);
while (location == -1)
h.changeStudent(head);
break;
case 5:
h.outputStudent(head);
break;
case 0:
break;
default:
cout << "输入错误,请重新输入" << endl;
Sleep(1000);
goto tt;
}
if (n == 0)
break;
}
system("pause");
return 0;
}
四、总结
本文主要介绍了一个考试报名系统的设计与实现。首先,通过需求分析强调了考试报名系统对于学校管理的重要性,以及随着学生和考试数量的增加,手工管理方式的局限性。接着,提出了采用计算机科学技术进行管理的优势,说明了开发考试报名系统的重要意义。在概要设计部分,详细介绍了系统设计的初始化、数据结构选择(链表)和类结构设计的逻辑,突出了链表在处理频繁的插入、删除和修改操作中的便利性,以及如何通过类结构和数据封装来简化程序设计。最后,通过调用关系图展示了系统中各个组件之间的相互作用和依赖关系,确保了系统设计的清晰性和高效性。整体上,该文档为读者提供了考试报名系统从需求分析到概要设计的全面视角,展现了系统设计的合理性和实用性。以上就是使用C++进行设计的考试报名管理系统的数据结构课程设计内容,感谢支持。