运用线性表实现学生选课系统

本文介绍了一个能够管理40000名学生和3000门课程的大学选课系统的实现,包括学生和课程信息的输入、查找、插入、删除功能,以及选课、查看选课信息等操作。程序具有健壮性和用户友好的界面,并使用链表数据结构存储学生和课程信息。

1、问题描述

为一所拥有接近 40000 名学生和 3000 门课程的大学,生成一个选课系统,具有
如下功能:
(1) 能够输入所有学生信息(学号,姓名,性别,…);
(2) 能够输入所有课程信息(课号,课名,学分,…);
(3) 能够查找、插入、删除学生记录;
(4) 能够查找、插入、删除课程记录;
(5) 能够输入学生选课信息,例如给定(学号 a,课号 b),就表示学生 a 注册
了课程 b;
(6) 能够输出某门课程的所有选课学生的名单,包含学生所有信息(学号、姓名、
性别……);
(7) 能够输出某位学生的所有选课课程清单,包含课程的所有信息(课号、课名、
学分……);

2、基本要求

(1) 程序要添加适当的注释,程序的书写要采用缩进格式 。
(2) 程序要具在一定的健壮性,即当输入数据非法时, 程序也能适当地做出反
应,如 插入删除时指定的位置不对 等等。
(3) 程序要做到界面友好,在程序运行时用户可以根据相应的提示信息进行操作。

3、数据结构的设计

(1)定义一个学生类型的链表,里面要包含学生的全部有效信息。
(2)定义链表 S_LinkList 存放学生结点。
(3)定义一个课程类型的链表,里面要包含课程的全部有效信息。
(2)定义链表 S_LinkList 存放课程结点。

4、要使用到的函数说明

(1)bool Num(string s)//根据 ASCII 值判断字符串中是否为数字,如果是返回 true,反之返回 false。
(2)int InitList_C(C_LinkList& C)//初始化课程链表,初始化成功返回OK,初始化失败返回 ERROR。
(3)int InitList_S(S_LinkList& S)//初始化学生链表,初始化成功返回OK,初始化失败返回 ERROR。
(4)void Input_C(C_LinkList& C) //输入课程信息。
(5)void Input_S(S_LinkList& S)//输入学生信息。
(6)int NumberSeek_S(S_LinkList S)//根据学号查找学生,找到了返回OK,输入的学号不是七位数字或者不存在该学号则返回 ERROR。
(7)void NameSeek_S(S_LinkList S)//根据姓名查找学生。
(8)void Insert_S(S_LinkList& S)//在学生链表中插入一个学生信息。
(9)void Delete_S(S_LinkList& S)//根据学号删除一个学生的信息。
(10)void ChooseCours(S_LinkList& S,C_LinkList& C)//学生进行选课。
(11)void Output_S(S_LinkList& S)//根据学号输出某学生所选择的课程。
(12)void NumberSeek_C(C_LinkList C)//根据课号查找课程。
(13)void NameSeek_C(C_LinkList C)//根据课程名查找课程。
(13)void Insert_C(C_LinkList& C)//在课程链表中插入一门课程信息。
(14)void Delete_C(C_LinkList& C)//根据课号删除一门课程的信息。
(15)void Output_C(C_LinkList& C)//根据课号输出选择某课的学生信息。
(16)主函数:int main()//进行各项操作。

5、具体代码

//PA1—前提:假设学号为 7 位数字
#include<iostream>
#include<stdlib.h>
#include<string>
#define OK 1
#define ERROR 0
using namespace std;

typedef struct Student{
    string s_number;//学生序号
    string s_name;//学生姓名
    string sex;//学生性别
    string c[1000];//学生所选课程的信息
    int k;//n 为 c 中元素个数
}Student;//定义学生类型

typedef struct Course{
    string c_number;//课号
    string c_name;//课名
    int score;//课程学分
    string s[1000];//选某课程学生的信息
    int m;//m 为 s 中元素个数
}Course;//定义课程类型

typedef struct S_Lnode{
    Student date;//数据域存放学生信息
    int S_length;//学生人数
    struct S_Lnode* next;//指针域
}*S_LinkList;//定义链表 S_LinkList 存放学生结点

typedef struct C_Lnode{
    Course date;//数据域存放课程信息
    int C_length;//课程数量
    struct C_Lnode* next;//指针域
}*C_LinkList;//定义链表 C_LinkList 存放课程结点

bool Num(string s) {
    for (int i = 0; i < s.size(); i++){
    int tmp = (int)s[i];
    if (tmp >= 48 && tmp <= 57) continue;
    else return false;
    } 
    return true;
}//根据 ASCII 值判断字符串中是否为数字

int InitList_C(C_LinkList& C) {
    C = new C_Lnode;
    if (!C) return ERROR;//分配空间失败
    C->next = NULL;C->C_length = 0;
    return OK;//分配空间成功
}//初始化课程链表

void Input_C(C_LinkList& C) {
    int m = 1;
    C_LinkList r = C;//尾指针
    C_LinkList c;//课程结点
    cout << "请输入课程信息" << endl;
    while (m) {
        c = new C_Lnode;
        cout << "课号:";cin >> c->date.c_number;
        int n = c->date.c_number.size();
        if (!Num(c->date.c_number) || n != 4){
            cout << "输入错误,课号应为 4 位数字,请重新输入!" << endl;continue;
            }
        cout << "课名:";cin >> c->date.c_name;
        cout << "学分:";cin >> c->date.score;
        cout << endl;
        c->next = NULL;r->next = c;r = c;
        C->C_length++;
        cout << "继续输入请按 1,退出输入请按 0:";
        cin >> m;
        }
        cout << "输入完毕,目前已输入" << C->C_length << "门课程" << endl;
}//输入课程信息

int InitList_S(S_LinkList& S) {
    S = new S_Lnode;
    if (!S) {
        cout << "初始化学生链表失败,未成功分配空间" << endl;
        return ERROR;
    }
    S->next = NULL;S->S_length = 0;
    cout << "初始化学生链表成功!";
    return OK;//分配空间成功
}//初始化学生链表

void Input_S(S_LinkList& S) {
    int m=1;
    S_LinkList r = S;//尾指针
    S_LinkList s;//学生结点
    cout << "请输入学生信息" << endl;
    while (m) {
        s = new S_Lnode;
        cout << "学号:";cin >> s->date.s_number;
        int n = s->date.s_number.size();
        if (!Num(s->date.s_number) || n != 7){
            cout << "输入错误,学号应为 7 位数字,请重新输入!" << endl;
            continue;
        }
        cout << "姓名:";cin >> s->date.s_name;
        cout << "性别:";
        cin >> s->date.sex;cout << endl;
        s->next = NULL;r->next = s;r = s;
        S->S_length++;
        cout << "继续输入请按 1,退出输入请按 0:";
        cin >> m;
    }
    cout << "输入完毕,目前已输入" << S->S_length << "名学生" << endl;
}//输入学生信息

int NumberSeek_S(S_LinkList S,string e, S_LinkList &p) {
    while (p && p->date.s_number != e)
        p = p->next;
    if (!p) return ERROR;
    return OK;
}//根据学号查找学生

void NameSeek_S(S_LinkList S) {
    S_LinkList s;//用于存放姓名为 e 的学生的信息
    string e;//e 为要查找的姓名
    S_LinkList p, q;
    p = S;
    s = new S_Lnode;s->next = NULL;s->S_length = 0;
    q = s;
    cout << "请输入要查找的姓名:";cin >> e;
    while (p->next) {
        if (p->next->date.s_name == e) {
        //将名字为 e 的学生存放于 s 中
            S_LinkList r;
            r = p->next;p->next = r->next;
            q->next = r;r->next = NULL;
            q = r;s->S_length++;
            delete r;
            p = p->next;
        }
        else
            p = p->next;
    }
    if (s->S_length == 0) {
        cout << "系统内目前不存在名字为" << e << "的学生" << endl;
         return;
    }
    else {
    cout << "系统内有" << s->S_length << "名学生姓名为" << e << "。具体信息如下" <<endl;
    q = s->next;
    while (q) {
        cout << "学号:" << q->date.s_number << " 姓名:" << q->date.s_name <<  " 性别:"  << q->date.sex << endl;q = q->next;
        }
    }
}//根据姓名查找学生

void Insert_S(S_LinkList& S) {
    int i;//插入到第 i 个位置上
    cout << "请输入要插入的位置:";cin >> i;
    S_LinkList p = S; int j = 0;//j 为计数器
    while (p && j < i - 1) {
        p = p->next;j++;}
        if (!p || j > i - 1){
        cout << "插入位置非法。" << endl;
        return;
    }
    S_LinkList s = new S_Lnode;
    cout << "请输入学生信息" << endl;cout << "学号:";cin >> s->date.s_number;
    if (!Num(s->date.s_number) || s->date.s_number.size() != 7){
        cout << "输入错误,学号应为 7 位数字!" << endl;
        return ;
    }
    cout << "姓名:";cin >> s->date.s_name;cout << "性别:";
    cin >> s->date.sex;
    s->next = p->next;p->next = s;
    cout << "插入完毕!" << endl;
}//在学生链表中插入一个学生信息

void Delete_S(S_LinkList& S) {
    string e;//要删除学生的学号
    cout << "请输入要删除学生的学号:";cin >> e;
    if (!Num(e) || e.size() != 7){
        cout << "输入错误,学号应为 7 位数字!" << endl;
        return ;
    }
    S_LinkList p = S;
    while (p->next&&p->next->date.s_number!=e) 
    {p = p->next;}
    if (!(p->next))
    {cout << "不存在学号为" << e << "的学生";return ;}
    S_LinkList q = p->next;p->next = q->next;
    delete q;cout << "删除成功!";
}//根据学号删除一个学生的信息

void ChooseCours(S_LinkList& S,C_LinkList& C) {
string e, n;//e 为学号,n 为课号
int c=1,i=0,j=0;//c 为是否继续选课的标志,i 和 j 分别为 s 和 c 数组的下标
S->date.k = 0;C->date.m = 0;
cout << "目前为选课系统" << endl;cout << "请输入你的学号和要选的课的课号" << endl;cout
<< "学号:"; cin >> e;
if (!Num(e) || e.size() != 7){cout << "输入错误,学号应为 7 位数字!" << endl;return ;}
S_LinkList p = S->next;
while (p && p->date.s_number != e) {p = p->next;}
if (!p){cout << "系统内暂时不存在学号为" << e << "的学生" << endl;return;}
while (c)
{
cout << "课号:"; cin >> n;
if (!Num(n) || n.size() != 4)
{cout << "输入错误,课号应为 4 位数字!" << endl;continue;}
else
{
C_LinkList q;
q = C->next;
while (q && q->date.c_number != n) {q = q->next;}
if (!q)
{cout << "系统内暂时不存在课号为" << n << "的课程" << endl;continue;}
else {
cout << "选课成功," << e << "选了课号为" << n << "的课。" << endl;
p->date.c[i] = q->date.c_number; p->date.c[++i] = q->date.c_name;
p->date.c[++i] = q->date.score;
p->date.k = i + 1;
q->date.s[j] = p->date.s_number; q->date.s[++j] = p->date.s_name;
q->date.s[++j] = p->date.sex;
q->date.m = j + 1;}
}
cout << "退出选课系统请输入 0,继续进行选课请输入 1:" ;cin >> c;
}
}//输入学生选课信息
void Output_S(S_LinkList& S) {
string e;//e 为学号
cout << "请输入学号:"; cin >> e;
if (!Num(e) || e.size() != 7)
{cout << "输入错误,学号应为 7 位数字!" << endl;return ;}
S_LinkList p = S;
while (p && p->date.s_number != e) {
p = p->next;}
if (!p){
cout << "系统内暂时不存在学号为" << e << "的学生" << endl;
return ;}
else
{
cout << "该学生信息如下" << endl;
cout << "学号:" << p->date.s_number << " 姓名:" << p->date.s_name << " 性别:
" << p->date.sex << endl;
cout << "该学生所选课程信息如下" << endl;
for (int i = 0; i < p->date.k; ) {
cout << p->date.c[i] << " " << p->date.c[++i] << " " << p->date.c[++i] <<
endl;}
}
}//输出某个学生所选择的课程
void NumberSeek_C(C_LinkList C) {
C_LinkList p;
p = C->next;
string n;//n 为要查找的课号
cout << "请输入要查找的课号:";cin >> n;
if (!Num(n) || n.size() != 7){
cout << "输入错误,课号应为 4 位数字!" << endl;
return ;}
while (p && p->date.c_number != n) {p = p->next;}
if (!p){
cout << "系统内暂时不存在课号为" << n << "的课程" << endl;
return ;}
else{
cout << "该课程信息如下" << endl;
cout << "课号:" << p->date.c_number << " 课名:" << p->date.c_name << " 学分:
" << p->date.score;}
}//根据课号查找课程
void NameSeek_C(C_LinkList C) {
C_LinkList c;//用于存放课程名为 n 的课程的信息
string n;//n 为要查找的课程名
C_LinkList p, q;
p = C;
c = new C_Lnode;c->next = NULL;c->C_length = 0;
q = c;
cout << "请输入要查找的课程名:";cin >> n;
while (p->next) {
if (p->next->date.c_name == n) {//将名字为 n 的课程存放于 c 中
C_LinkList r;
r = p->next;
p->next = r->next;
q->next = r;
r->next = NULL;
q = r;
c->C_length++;
delete r;
p = p->next;}
else
p = p->next;
}
if (c->C_length == 0) {
cout << "系统内目前不存在课程名为" << n << "的课程" << endl;
return ;}
else {
cout << "系统内有" << c->C_length << "门课程名为" << n << "。具体信息如下" << endl;
q = c->next;
while (q) {
cout << "课号:" << q->date.c_number << " 课程名:" << q->date.c_name << " 学分:" << q->date.score << endl;
q = q->next;}
}
}//根据课程名查找课程
void Insert_C(C_LinkList& C) {
int i;//插入到第 i 个位置上
cout << "请输入要插入的位置:";cin >> i;
C_LinkList p = C; int j = 0;//j 为计数器
while (p && j < i - 1) {
p = p->next;j++;}
if (!p || j > i - 1){
cout << "插入位置非法。" << endl;
return ;}
C_LinkList c = new C_Lnode;
cout << "请输入课程信息" << endl;cout << "课号:";cin >> c->date.c_number;
if (!Num(c->date.c_number) || c->date.c_number.size() != 4){
cout << "输入错误,课号应为 4 位数字!" << endl;
return ;}
cout << "课名:";cin >> c->date.c_name;
cout << "学分:";cin >> c->date.score;
c->next = p->next;
p->next = c;
cout << "插入完毕!" << endl;
}//在课程链表中插入一个课程信息
void Delete_C(C_LinkList& C) {
string n;//要删除课程的课号
cout << "请输入要删除课程的课号:";cin >> n;
if (!Num(n) || n.size() != 4){
cout << "输入错误,课号应为 4 位数字!" << endl;
return;}
C_LinkList p = C;
while (p->next && p->next->date.c_number != n) {p = p->next;}
if (!(p->next)){
cout << "不存在课程号为" << n << "的课程";
return;}
C_LinkList q = p->next;
p->next = q->next;
delete q;
cout << "删除成功!";
}//根据课号删除课程信息
void Output_C(C_LinkList& C) {
string n;//n 为课号
cout << "请输入课号:"; cin >> n;
if (!Num(n) || n.size() != 4){
cout << "输入错误,课号应为 4 位数字!" << endl;
return ;}
C_LinkList p = C;
while (p && p->date.c_number != n) {p = p->next;}
if (!p){
cout << "系统内暂时不存在课号为" << n << "的课程" << endl;
return;}
else{
cout << "该课程信息如下" << endl;
cout << "课号:" << p->date.c_number << " 课名:" << p->date.c_name << " 学分:
" << p->date.score << endl;
cout << "该课程所选学生信息如下" << endl;
for (int i = 0; i < p->date.m;)
{cout << p->date.s[i] << " " << p->date.s[++i] << " " << p->date.s[++i] << endl;}
}
}//输出选择某门课程所有学生的信息
int main()
{
int k;//k 为函数返回值
int ch=0;//ch 为操作数
S_LinkList S;C_LinkList C;
InitList_S(S);InitList_C(C);
cout << "*******************************" << endl;
cout << "===请选择以下数字进行操作===" << endl;
cout << "1 输入学生信息" << endl;
cout << "2 输入课程信息" << endl;
cout << "3 根据学号查找学生信息" << endl;
cout << "4 根据姓名查找学生信息" << endl;
cout << "5 插入学生信息" << endl;
cout << "6 删除学生信息" << endl;
cout << "7 根据课号查找课程信息" << endl;
cout << "8 根据课名查找课程信息" << endl;
cout << "9 插入课程信息" << endl;
cout << "10 删除课程信息" << endl;
cout << "11 学生进行选课" << endl;
cout << "12 输出课程所选学生名单" << endl;
cout << "13 输出学生选课课程清单" << endl;
cout << "========退出请输入-1========" << endl;
cout << "*******************************" << endl;
while (ch != -1){
cout << "请输入要进行的操作(退出请输入-1):"; cin >> ch;
switch (ch){
case 1:
Input_S(S); break;
case 2:
Input_C(C); break;
case 3:
{
S_LinkList p;
p = S->next;
string e;//e 为要查找的学号
cout << "请输入要查找的学号:";cin >> e;
if (!Num(e) || e.size() != 7)
cout << "输入错误,学号应为 7 位数字!" << endl;
k = NumberSeek_S(S, e, p);
if (k == 0)
cout << "系统内暂时不存在该学号的学生" << endl;
else{
cout << "该学生信息如下" << endl;
cout << "学号:" << p->date.s_number << " 姓名:" << p->date.s_name <<
" 性别:" << p->date.sex;}
break;
}
case 4:
NameSeek_S(S);break;
case 5:
Insert_S(S); break;
case 6:
Delete_S(S); break;
case 7:
NumberSeek_C(C); break;
case 8:
NameSeek_C(C); break;
case 9:
Insert_C(C); break;
case 10:
Delete_C(C); break;
case 11:
ChooseCours(S, C); break;
case 12:
Output_C(C); break;
case 13:
Output_S(S); break;
}
}
}
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值