程序设计篇(1):学生经验值管理系统(单链表实现)

/*
 ********************************************
        学 生 经 验 值 管 理 系 统 (简易)
 ********************************************
    编译环境: Dev-C++5.10 
    使用语言: C++ 
    实现方式: 单链表 
    初步实现功能:
        1、导入文件建学生经验值表    
        2、插入学生                  
        3、删除学生                  
        4、显示全部学生信息          
        5、为某学号学生加指定经验值  
        6、为某学号学生减指定经验值 
        7、按姓名查找学生经验值      
        8、求经验值最高的学生信息    
        9、存盘并退出   
    此处文件Student.txt 为自行建立。
    (也可自行添加构建文件的功能)     
 ******************************************** 
*/
#include <iostream>
#include <fstream>
#include <string>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAXSIZE 100
using namespace std;
bool undoing = false;

// 学生表结点 
typedef struct Student
{
    string s_Number;            // 学号 
    string s_Name;              // 姓名 
    double s_ExpVal;            // 经验值 
    int s_Length;               // 表长 
    struct Student *next;
} Student, *StudentList;

/*************************************************************************/
// 栈结点 
typedef struct
{
    string num;            // 学号 
    string name;           // 姓名 
    double expVal;         // 经验值 

    double changeExpVal;   // 增加或减少的经验值
    string blackNum;       // 位置意义上的:被删除学生的下一个学生的学号 
    string oper;           // 进行的操作 "i""d1""d2""+""-"代表 插入 表尾删除 表中删除 加经验 减经验 
} SNode;
// 栈结构 
typedef struct
{
    SNode *Base;
    SNode *Top;
    int stackSize;
} Stack;
// 栈初始化 
void InitStack(Stack &S)
{   
    S.Base = new SNode[MAXSIZE]; 
    if(!S.Base) exit(OVERFLOW);     
    S.Top = S.Base;                
    S.stackSize = MAXSIZE;          
}
// 入栈 
void Push(Stack &S, SNode node)
{   
    if(S.Top-S.Base == MAXSIZE) return;   
    *S.Top++ = node;                   // 压入栈顶,栈顶指针加1
}
// 出栈 
void Pop(Stack &S, SNode &node)
{   
    if(S.Top == S.Base) return;   // 栈空
    node = *--S.Top;                   // 栈顶指针减1,将栈顶元素赋给e
}

/*************************************************************************/

/*-----------------------------------------------------------------------*/
// 1、导入文件建学生经验值表
int CreateList(StudentList &L,Stack &stack)
{
    L = new Student;            // 初始化表 
    L->next = NULL;
    L->s_Length = 0;

    ifstream Input("Student.txt",ios::in);
    if(!Input)
    {
        cout<<"Cannot open the Student.txt."<<endl;
        return ERROR;
    }

    Student *T_Stu;             // 临时结构体变量用于建立结点 
    Student *F_List;            // 跟踪表结点
    F_List = L; 
    while(!Input.eof())         // 文本数据的输出 
    {
        T_Stu = new Student;
        Input>>T_Stu->s_Number;
        Input>>T_Stu->s_Name;
        Input>>T_Stu->s_ExpVal;
        T_Stu->next = NULL;

        F_List->next = T_Stu;
        F_List = T_Stu;
        L->s_Length++;
    }

    Input.close();
    if(!L) return ERROR;
    InitStack(stack);
    return OK;
}

// 2、插入学生(某学号前)
int InsertStudent(StudentList &L,string T_Number,bool Judge,Stack &stack)
{
    Student *N_Stu;         // 新进学生 
    Student *F_T_Stu;       // 新进学生的后继结点 
    Student *B_T_Stu;       // 新进学生的前驱结点 
    F_T_Stu = L;
    B_T_Stu = L;

    if(Judge == 1)          // 若在表尾插入新进学生 
    {
        while(F_T_Stu->next)                        // 搜位置 
            F_T_Stu = F_T_Stu->next;

        N_Stu = new Student;                        // 新进学生的信息 
        cout<<"请输入新进学生的信息:"<<endl;
        cout<<"学号:";
        cin>>N_Stu->s_Number;
        cout<<"姓名:";
        cin>>N_Stu->s_Name;
        cout<<"经验值:";
        cin>>N_Stu->s_ExpVal;
        N_Stu->next = NULL;

        F_T_Stu->next = N_Stu;                      // 嵌入表尾 
        L->s_Length++;

        if(undoing == false)
        {
            /*-----*/           // 压入撤销栈 
            SNode node;
            node.num = N_Stu->s_Number;
            node.name = N_Stu->s_Name;
            node.expVal = N_Stu->s_ExpVal;
            node.oper = "i";
            node.changeExpVal = 0;
            node.blackNum = "";
            Push(stack,node);
            /*-----*/
        }

        return OK;
    }
                            // 若在表中插入新进学生 
    while(F_T_Stu && F_T_Stu->s_Number!=T_Number)   // 搜位置 
    {
        B_T_Stu = F_T_Stu;
        F_T_Stu = F_T_Stu->next;
    }

    if(!F_T_Stu)
    {
        cout<<"找不到学号为 "<<T_Number<<"的学生!"<<endl;
        return ERROR;
    }

    N_Stu = new Student;                            // 新进学生的信息 
    cout<<"请输入新进学生的信息:"<<endl;
    cout<<"学号:";
    cin>>N_Stu->s_Number;
    cout<<"姓名:";
    cin>>N_Stu->s_Name;
    cout<<"经验值:";
    cin>>N_Stu->s_ExpVal;

    B_T_Stu->next = N_Stu;                          // 嵌入表中 
    N_Stu->next = F_T_Stu;
    L->s_Length++;

    if(undoing == false)
    {
        /*-----*/           // 压入撤销栈 
        SNode node;
        node.num = N_Stu->s_Number;
        node.name = N_Stu->s_Name;
        node.expVal = N_Stu->s_ExpVal;
        node.oper = "i";
        node.changeExpVal = 0;
        node.blackNum = "";
        Push(stack,node);
        /*-----*/
    }

    return OK;
} 

// 3、删除学生
int DeleteStudent(StudentList &L,string T_Number,Stack &stack)
{
    if(!L)
    {
        cout<<"表为空!无法删除!"<<endl;
        return ERROR;
    }
    Student *F_T_Stu;           // 指向将要删除的结点 
    Student *B_T_Stu;           // 指向将要 被删除的结点 的前驱结点 
    F_T_Stu = B_T_Stu = L;

    while(F_T_Stu && F_T_Stu->s_Number!=T_Number)   // 搜位置 
    {
        B_T_Stu = F_T_Stu;
        F_T_Stu = F_T_Stu->next;
    }

    if(!F_T_Stu)
    {
        cout<<"找不到学号为 "<<T_Number<<"的学生!"<<endl;
        return ERROR;
    }

    B_T_Stu->next = F_T_Stu->next;                  // 将结点从表中除去 

    if(undoing == false)
    {
        /*-----*/           // 压入撤销栈 
        SNode node;
        if(F_T_Stu->next)   // 表中删除 
        {
            node.num    = F_T_Stu->s_Number;
            node.name   = F_T_Stu->s_Name;
            node.expVal = F_T_Stu->s_ExpVal;
            node.oper    = "d2";
            node.changeExpVal = 0;
            node.blackNum     = F_T_Stu->next->s_Number;
            Push(stack,node);
        }
        else                // 表尾删除 
        {
            node.num    = F_T_Stu->s_Number;
            node.name   = F_T_Stu->s_Name;
            node.expVal = F_T_Stu->s_ExpVal;
            node.oper   = "d1";
            node.changeExpVal = 0;
            node.blackNum     = "";
            Push(stack,node);
        }
        /*-----*/
    }

    delete F_T_Stu;                                 // 释放被删除的结点 
    L->s_Length--;
    return OK;
}

// 4、显示全部学生信息
void DisplayList(StudentList L)
{
    Student *F_List;
    F_List = L->next;

    cout<<"学生经验值表:"<<endl;
    cout<<" _______________________________________________"<<endl;
    cout<<"|    学号  |   姓名  |   经验值 |"<<endl;
    cout<<"------------------------------------------------"<<endl;
    for(int i=1; i<=L->s_Length; i++)
    {
        cout<<"|    "<<F_List->s_Number<<"  ";
        cout<<"|    "<<F_List->s_Name<<"    ";
        cout<<"|    "<<F_List->s_ExpVal<<"  |"<<endl;
        cout<<"------------------------------------------------"<<endl;
        F_List = F_List->next;
    }       

    cout<<"打印完毕."<<endl<<endl;
} 

// 5、为某学号学生加指定经验值
int IncreaseExpVal(StudentList &L,string T_Number,Stack &stack)
{
    double Value;           // 将要增加的经验值 
    Student *T_Stu;         // 指向将要操作的学生 
    T_Stu = L;

    while(T_Stu && T_Stu->s_Number!=T_Number)   // 搜位置 
        T_Stu = T_Stu->next;

    if(!T_Stu)
    {
        cout<<"找不到学号为 "<<T_Number<<"的学生!"<<endl;
        return ERROR;
    }

    cout<<"请问要给学生 "<<T_Stu->s_Name<<" 加多少经验值?:";
    cin>>Value;             // 加经验值                 

    T_Stu->s_ExpVal += Value;

    if(undoing == false)
    {
        /*-----*/           // 压入撤销栈 
        SNode node;
        node.num = T_Stu->s_Number;
        node.name = T_Stu->s_Name;
        node.expVal = T_Stu->s_ExpVal;
        node.oper = "+";
        node.changeExpVal = Value;
        node.blackNum = "";
        Push(stack,node);
        /*-----*/
    }


    return OK;
} 

// 6、为某学号学生减指定经验值 
int DecreaseExpVal(StudentList &L,string T_Number,Stack &stack)
{
    double Value;           // 将要减少的经验值
    Student *T_Stu;         // 指向将要操作的学生 
    T_Stu = L;

    while(T_Stu && T_Stu->s_Number!=T_Number)   // 搜位置
        T_Stu = T_Stu->next;

    if(!T_Stu)
    {
        cout<<"找不到学号为 "<<T_Number<<"的学生!"<<endl;
        return ERROR;
    }

    cout<<"请问要给学生 "<<T_Stu->s_Name<<" 减多少经验值?:";
    cin>>Value;             // 减经验值

    T_Stu->s_ExpVal -= Value;

    if(undoing == false)
    {
        /*-----*/           // 压入撤销栈 
        SNode node;
        node.num = T_Stu->s_Number;
        node.name = T_Stu->s_Name;
        node.expVal = T_Stu->s_ExpVal;
        node.oper = "-";
        node.changeExpVal = Value;
        node.blackNum = "";
        Push(stack,node);
        /*-----*/
    }

    return OK;
}

// 7、按姓名查找学生经验值
int SearchExpVal(StudentList L,string T_Name)
{
    Student *T_Stu;         // 将要操作的学生 
    T_Stu = L;  

    while(T_Stu && T_Stu->s_Name!=T_Name)   // 搜位置 
        T_Stu = T_Stu->next;

    if(!T_Stu)
    {
        cout<<"找不到姓名为 "<<T_Name<<"的学生!"<<endl;
        return ERROR;
    }

    cout<<"学生 "<<T_Stu->s_Name<<" 的经验值为:";  // 输出 
    cout<<T_Stu->s_ExpVal<<endl<<endl;

    return OK;
}

// 8、求经验值最高的学生信息
void MaxExpVal(StudentList L)
{
    Student *T_Stu;     // 追踪表中各结点 
    double   T_Max;     // 储存表中最大经验值 

    T_Stu = L->next;
    T_Max = T_Stu->s_ExpVal;

    for(int i=2; i<=L->s_Length; i++)   // 找最大经验值 
    {
        T_Stu = T_Stu->next;
        if(T_Stu->s_ExpVal > T_Max)
        {
            T_Max = T_Stu->s_ExpVal;
        }
    }   

                                        // 打印拥有最大经验值的学生信息 
    T_Stu = L;  
    cout<<"最高经验值学生:"<<endl;     
    cout<<" _______________________________________________"<<endl;
    cout<<"|    学号  |   姓名  |   经验值 |"<<endl;
    cout<<"------------------------------------------------"<<endl;
    for(int i=1; i<=L->s_Length; i++)
    {
        T_Stu = T_Stu->next;
        if(T_Stu->s_ExpVal==T_Max)
        {
            cout<<"|    "<<T_Stu->s_Number<<"   ";
            cout<<"|    "<<T_Stu->s_Name<<" ";
            cout<<"|    "<<T_Stu->s_ExpVal<<"   |"<<endl;
            cout<<"------------------------------------------------"<<endl;
        }
    }
    cout<<"打印完毕."<<endl<<endl;
} 

// 9、撤销
// "i""d1""d2""+""-"代表 插入 表尾删除 表中删除 加经验 减经验
int Undo(StudentList &L,Stack &stack)
{
    undoing == true;
    SNode node;
    Pop(stack,node);

    if(node.oper == "i")
    {
        DeleteStudent(L,node.num,stack);
    }
    else if(node.oper == "d1")
    {
        Student *N_Stu;
        Student *F_T_Stu;
        F_T_Stu = L;

        while(F_T_Stu->next)                        // 搜位置 
            F_T_Stu = F_T_Stu->next;

        N_Stu = new Student; 
        N_Stu->s_Number = node.num;       
        N_Stu->s_Name = node.name;
        N_Stu->s_ExpVal= node.expVal;  
        N_Stu->next = NULL;    

        F_T_Stu->next = N_Stu;        // 嵌入表尾 
        L->s_Length++;
    }
    else if(node.oper == "d2")
    {
        Student *N_Stu;
        Student *F_T_Stu;   
        Student *B_T_Stu;    
        F_T_Stu = L;
        B_T_Stu = L;

        while(F_T_Stu && F_T_Stu->s_Number!=node.blackNum)   // 搜位置 
        {
            B_T_Stu = F_T_Stu;
            F_T_Stu = F_T_Stu->next;
        }

        N_Stu = new Student; 
        N_Stu->s_Number = node.num;           
        N_Stu->s_Name = node.name;
        N_Stu->s_ExpVal = node.expVal;  

        B_T_Stu->next = N_Stu;
        N_Stu->next = F_T_Stu;
        L->s_Length++;
    }
    else if(node.oper == "+")
    {
        Student *T_Stu;         // 指向将要操作的学生 
        T_Stu = L;

        while(T_Stu && T_Stu->s_Number!=node.num)   // 搜位置 
            T_Stu = T_Stu->next;
        T_Stu->s_ExpVal -= node.changeExpVal;
    }
    else if(node.oper == "-")
    {
        Student *T_Stu;         // 指向将要操作的学生 
        T_Stu = L;

        while(T_Stu && T_Stu->s_Number!=node.num)   // 搜位置 
            T_Stu = T_Stu->next;
        T_Stu->s_ExpVal += node.changeExpVal;
    }

    undoing == false;
    return OK;
}

// 10、存盘并退出
int SaveList(StudentList L)
{
    ofstream Output("Student.txt",ios::out);
    if(!Output)
    {
        cout<<"Cannot open the file Student.txt."<<endl;
        return ERROR;
    }

    Student *T_Stu;         // 追踪表中各结点 
    T_Stu = L->next;

    for(int i=1; i<=L->s_Length; i++)
    {
        Output<<endl<<T_Stu->s_Number<<endl;
        Output<<T_Stu->s_Name<<endl;
        Output<<T_Stu->s_ExpVal;
        T_Stu = T_Stu->next;
    }

    Output.close();
    return OK;
} 
/*-----------------------------------------------------------------------*/

int main()
{
    int     choose  = 0;
    bool    Judge   = false;
    string  Number  = " ";
    string  Name    = " ";
    StudentList List;
    Stack   stack;

    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<<"*********************************************"<<endl;

    while(1)
    {
        cout<<"请输入您的选择:";
        cin>>choose;

        switch(choose)
        {
            case 1:
                if(CreateList(List,stack))
                    cout<<"导入成功!建立学生经验值表!"<<endl<<endl;
                else
                {
                    cout<<"导入失败!文件异常!"<<endl<<endl;
                    return ERROR;
                }
                continue;
            case 2:
                cout<<"是否在表尾插入?(是则输入1,否则输入0):";
                cin>>Judge;
                if(Judge!=0 && Judge!=1)
                {
                    cout<<"输入错误!请重新进行操作!"<<endl<<endl;
                    continue;
                }
                if(Judge==0)
                {
                    cout<<"请问在哪位学生前插入?(请输入学号):";
                    cin>>Number;
                }
                else
                {
                    Number = " ";
                }
                if(InsertStudent(List,Number,Judge,stack))
                    cout<<"插入成功!"<<endl<<endl;
                else
                    cout<<"插入失败!请重新进行操作!"<<endl<<endl;
                continue;
            case 3:
                cout<<"请问要删除哪位学生的信息?(请输入学号):";
                cin>>Number;
                if(DeleteStudent(List,Number,stack))
                    cout<<"删除成功!"<<endl<<endl;
                else
                    cout<<"删除失败!请重新进行操作!"<<endl<<endl;
                continue;
            case 4:
                DisplayList(List);
                continue;
            case 5:
                cout<<"请问要给哪位学生加经验值?(请输入学号):";
                cin>>Number;
                if(IncreaseExpVal(List,Number,stack))
                    cout<<"增加成功!"<<endl<<endl;
                else
                    cout<<"增加失败!请重新进行操作!"<<endl<<endl;
                continue;
            case 6:
                cout<<"请问要给哪位学生减经验值?(请输入学号):";
                cin>>Number;
                if(DecreaseExpVal(List,Number,stack))
                    cout<<"减少成功!"<<endl<<endl;
                else
                    cout<<"减少失败!请重新进行操作!"<<endl<<endl;
                continue;
            case 7:
                cout<<"请问要查询哪位学生的经验值?(请输入姓名):";
                cin>>Name;
                if(!SearchExpVal(List,Name))
                    cout<<"查询失败!请重新进行操作!"<<endl<<endl;
                continue;
            case 8:
                 MaxExpVal(List);
                 continue;
            case 9:
                 if(Undo(List,stack))
                    cout<<"撤销完毕!"<<endl<<endl;
                 continue;
            case 10:
                if(SaveList(List))
                {
                    cout<<"数据已保存!"<<endl;
                    cout<<"正在退出程序..."<<endl;
                    cout<<"程序正常结束.感谢您的支持,欢迎下次使用!"<<endl; 
                    break;
                }
                else
                    cout<<"数据保存失败!请重新进行操作!"<<endl<<endl;
                continue;
            default:
                cout<<"输入异常!程序异常结束!!!"<<endl<<endl;
                break;
        }       
        break;
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值