【数据结构与算法】学校运动会管理系统(C/C++)

这是一个完整的项目,若有需要整个项目的压缩包(源代码、文档、md文件等)可私聊发送”学校运动会管理系统”。

问题描述

  1. 在“学校运动会管理系统”中,设有n个单位参加运动会(单位可是学院、系、年级等,应可设定)共有男子比赛项目m,女子比赛项目w。 每个学院可以选择参赛项目,运动员参赛项目应有所限制,如最多只能参加3项单项比赛。
  2. 各项目名次选取应可设置,随系统环境而变化,如:参赛人数超过6人,取前5名:第一名得7分,第二名得5分,第三名得3分,第四名得2分,第五名得1分;参赛人数不超过6人,取前3名:第一名得5分,第二名得3分,第三名得2分。参赛人数不足4人的项目将取消等等规定。
  3. 系统设置内容:
    参赛单位名称; 比赛项目设置(注意比赛成绩排序中田赛和径赛的区别)运动员参赛项目限制; 选取名次设置;

系统功能性需求

“学校运动会管理系统”应该包含但不限于以下功能:

  • 参赛项目发布(人为安排时间和场地和项目名字)
  • 运动员报名登记。登记限制要求按问题描述的要求;(最多报两个项目、前后不应有项目、男女项目不互通)
  • 参赛信息查询。查看参赛学院信息和比赛项目信息;
  • 秩序册自动生成;需满足条件,如:
    1. 竞赛项目避免场地冲突
    2. 同一个运动员参加的不同比赛项目不应有时间上的交叉
    3. 一个运动员应尽可能避免参加2个连续项目;运动会总时间应该尽可能短;
    4. 运动会上午和下午比赛项目数应较为平均
    5. 比赛已结束就不能在报名、修改运动员信息了(成绩录入即为比赛结束)
  • 比赛成绩查询(没有录入成绩的项目成绩为无)。可以按比赛项目(排名)、参赛学院(不排只列学院、名成绩)、参赛运动员(学院、项目、名字、成绩)查看比赛成绩;如:

    100米:
    第一名 张三 11''2
    第二名 李四 11''7
    第三名 王五 11''9
    第四名 刘六 12''5
    第五名 赵七 12''8
    第六名 周八 13''1
    跳高:
    第一名 张三 2米02
    第二名 李四 2米
    第三名 王五 1米9
    第四名 刘六 1米88
    第五名 赵七 1米82
    第六名 周八 1米8

  • 数据备份\
  • 前提:报名项目大于3人。成绩录入(输入一个项目后将所有人的成绩一一输入)

报告内容

写在前面:该项目已经完成了绝大部分功能,因为当初时间比较赶,并没有实现报告的全部功能~

1. 数据结构设计

说明程序用到的数据结构的定义,主程序的流程及各模块之间的层次关系

1.1数据结构定义

本程序共定义了三个类:SportsManager(管理类)、Sporter(每一条运动员的信息)、Event(项目),其中SportsManager中有publicprivate之分。
运动员的报名信息表是用动态数组来实现的,若有新的运动员数据添加进来则为其开辟一块新的空间;而比赛项目信息是用静态数组来实现的。

1.2主程序的流程图

image1
image1主程序的流程图

1.3各模块调用关系

  • 进入程序
image1
image2 进入程序模块调用图
  • 进入运动员报名登记
image1
image3 进入运动员报名登记模块调用图
  • 进入运动员删除
image1
image4 进入运动员删除模块调用图
  • 进入运动员修改
image1
image5 进入运动员修改模块调用图
  • 查询比赛信息
image1
image6 进入查询比赛模块调用图
  • 进入成绩录入
image1
image7 进入成绩录入模块调用图
  • 进入成绩查询
image1
image8 进入成绩查询模块调用图

2.程序设计

实现概要设计中的数据类型,对主程序、模块及主要操作写出伪代码,画出函数的调用关系

2,1数据类型

数据类型:string、vector、int、bool、float

2.2主程序、模块、主要操作伪代码

  • main函数和伪代码
image1
image9 main函数和伪代码
  • 保存运动员信息函数和伪代码
image1
image10 保存运动员信息函数和伪代码
  • 查询项目信息函数和伪代码
image1
image11 查询项目信息函数和伪代码
  • 获取运动员报名个数函数和伪代码
image1
image12 获取运动员报名个数函数和伪代码

3.调试分析

设计实现过程中遇到的问题及如何解决的;算法的复杂度分析;经验体会

首先遇到的是集成开发环境不同而导致项目在进行交接和功能的拼接上出现了问题,一开始用的是DEV C++,但由于DEV C++不知道如何进行多文件编译,于是就使用了visual studio 2022vs code来进行开发,但是visual studio又不支持将源文件和头文件复制粘贴出来,所有导致程序文件传输的效率很低,最后统一使用visual studio 2022这个IDE来进行开发。其次是惯用语言不同而导致开发起来难度较大,此次项目主要是用C++来编写的。在算法上采用了动态数组和静态数组相结合的方式来节约整个程序的空间,对于时间复杂度最多是O(n*n)由于一开始选取的数据结构没有安排好,导致了没有采用更优的算法来优化整个程序。除此之外,在遇到bug时组员能及时面对面一起解决。虽然整个程序仍然存在许多可以优化的地方,但是每个人都从中收获到了不少。

4.测试结果

列出测试结果,包括输入和输出

  • 选择1查询比赛项目的输出
image1
image13 查询比赛项目的输出
  • 选择运动员报名登记的输入和输出
image1
image14 选择运动员报名登记的输入和输出
  • 选择3删除运动员报名信息的输入和输出
image1
image15 删除运动员报名信息的输入和输出
  • 选择4查询运动员报名信息的输入和输出
image1
image16 查询运动员报名信息的输入和输出
  • 选择5修改运动员报名信息的输入和输出
image1
image17 修改运动员报名信息的输入和输出
  • 选择6参赛信息查询的输入和输出
image1
image18 参赛信息查询的输入和输出
  • 选择7查看秩序册的输出
image1
image19 查看秩序册的输出
  • 选择8录入比赛成绩的输入和输出
image1
image20 录入比赛成绩的输入和输出
  • 选择9比赛成绩查询的输入和输出
image1
image21 比赛成绩查询的输入和输出
  • 选择10各学院得分统计的输出
image1
image22 各学院得分统计的输出

5.用户使用说明

给出主界面及主要功能界面

  • 主界面及主要功能界面
image1
image23 主界面

6.附录

给出源程序文件清单,如:
Node.H //节点实现单元
SetDemos.C //主程序

共有三个头文件:event.h \ sporter.h \ sportsManager.h
两个源文件:sportsManagementSystem.cpp \ sportsManager.cpp
以及三个txt文件:program.txt \ schedule.txt \ sporterForm.txt

image1
image24

注意:在导入项目若改变存放头文件和txt文件的位置,则需要修改其在程序中的相对位置,否则不能正常运行。可能会出现中文乱码的情况,修改一下编码格式就可以了。

项目完整代码

event.h

#pragma once
#include <string>
using namespace std;

//运动会项目类
class Event {
public:
    //名称
    string m_name;
    //性别限制
    string m_gender;
    //比赛时间
    string m_time;
    //比赛场地
    string m_venue;
    //该项目成绩已录入的标志
    bool hasInputGrade = false;

    //排序方法标志
    char m_sortMark;

    //项目的构造函数
    Event(string name, string gender, string venue, string time, char sortMark):m_name(name), m_gender(gender), m_venue(venue), m_time(time), m_sortMark(sortMark){

    }
};

program.txt

日程安排表:
第1日
08:30 - 10:00	跑道:50米(男)、50米(女)		沙地:跳远(男)		体育馆:引体向上	足球场:铅球(男) 	篮球场:跳绳(男)
10:00 - 11:40	跑道:200米(男)、200米(女)		沙地:跳远(女) 		体育馆:仰卧起坐	足球场:铅球(女) 	篮球场:跳绳(女)
14:30 - 16:00	跑道:4×100米(男)、4×100米(女)		沙地:三级跳远(男)	体育馆:跳高(女)	足球场:标枪(男)	篮球场:三步上篮(女)
16:00 - 17:30	跑道:1000米跑(男)、800米跑(女)		沙地:三级跳远(女)	体育馆:跳高(男)	足球场:标枪(女) 	篮球场:三步上篮(男)
----------------------------------------------------------------------------------------------------------------------------------------
第2日
08:30 - 10:00	跑道:5000米跑(男)、5000米跑(女)	沙地:立定跳远(女)	体育馆:击剑(男)	足球场:铁饼(男) 	篮球场:拔河(女)
10:00 - 11:40	跑道:110米跨栏(男)			沙地:立定跳远(男)	体育馆:击剑(女)	足球场:铁饼(女) 	篮球场:拔河(男)
14:30 - 16:00	跑道:110米跨栏(女)                	沙地:马术(男) 		体育馆:体操(男)	足球场:棒球(男) 	篮球场:射箭(女)
16:00 - 17:30	跑道:马拉松				沙地:马术(女) 		体育馆:体操(女)	足球场:棒球(女) 	篮球场:射箭(男)
----------------------------------------------------------------------------------------------------------------------------------------

规则细则:
项目成绩录入后视为项目已经结束,不能再进行有关运动员的操作。如:运动员报名登记或修改运动员报名信息。
项目的总参赛人数不影响得分。第一名得3分,第二名得2分,第三名得1分,其余的不得分。若参赛人数小于三人,项目不取消并且得分不变。

schedule.txt

50m跑 男 跑道 0108:30-10:00 <
50m跑 女 跑道 0108:30-10:00 <
跳远 男 沙地 0108:30-10:00 >
引体向上 男 体育馆 0108:30-10:00 > 
铅球 男 足球场 0108:30-10:00 >
跳绳 男 篮球场 0108:30-10:00 >
200m跑 男 跑道 0110:30-11:40 <
200m跑 女 跑道 0110:30-11:40 <
跳远 女 沙地 0110:30-11:40 >
仰卧起坐 女 体育馆 0110:30-11:40 >
铅球 女 足球场 0110:30-11:40 >
跳绳 女 篮球场 0110:30-11:40 >
4*100m跑 男 跑道 0114:30-16:00 <
4*100m跑 女 跑道 0114:30-16:00 <
三级跳远 男 沙地 0114:30-16:00 >
跳高 女 体育馆 0114:30-16:00 >
标枪 男 足球场 0114:30-16:00 >
三步上篮 女 篮球场 0114:30-16:00 <
1000m跑 男 跑道 0116:00-17:30 <
800m跑 女 跑道 0116:00-17:30 <
三级跳远 女 沙地 0116:00-17:30 >
跳高 男 体育馆 0116:00-17:30 >
标枪 女 足球场 0116:00-17:30 >
三步上篮 男 篮球场 0116:00-17:30 <
5000m跑 男 跑道 0208:30-10:00 <
5000m跑 女 跑道 0208:30-10:00 <
立定跳远 女 沙地 0208:30-10:00 >
击剑 男 体育馆 0208:30-10:00 >
铁饼 男 足球场 0208:30-10:00 >
拔河 女 篮球场 0208:30-10:00 >
110m跨栏 男 跑道 0210:00-11:40 <
立定跳远 男 沙地 0210:00-11:40 >
击剑 女 体育馆 0210:00-11:40 >
铁饼 女 足球场 0210:00-11:40 >
拔河 男 篮球场 0210:00-11:40 >
110m跨栏 女 跑道 0214:00-16:00 <
马术 男 沙地 0214:00-16:00 >
体操 男 体育馆 0214:00-16:00 >
棒球 男 足球场 0214:00-16:00 >
射箭 女 篮球场 0214:00-16:00 >
马拉松 男 跑道 0216:00-17:30 <
马拉松 女 跑道 0216:00-17:30 <
马术 女 沙地 0216:00-17:30 >
击剑 女 体育馆 0216:00-17:30 >
棒球 女 足球场 0216:00-17:30 >
射箭 男 篮球场 0216:00-17:30 >

sporter.h

#pragma once
#include <string>
#include <vector>
#include "event.h"
using namespace std;

class Sporter{
    public:
        //运动员所在学院
        string m_college;
        //运动员姓名
        string m_name;
        //运动员的性别
        string m_gender;
        //运动员报名的项目的索引
        int m_registeredEventNum;
        //运动员该项目的成绩
        string m_grade = "无";

        int m_rank = -1;
        int m_score = -1;

        //构造函数
        //有成绩时的构造函数
        Sporter(string college, string name, string gender, int registeredEventNum, string grade, int rank, int score):m_college(college), m_name(name), m_gender(gender), m_registeredEventNum(registeredEventNum), m_grade(grade), m_rank(rank), m_score(score) {
            
        }
        //无成绩时的构造函数
        Sporter(string college, string name, string gender, int registeredEventNum):m_college(college), m_name(name), m_gender(gender), m_registeredEventNum(registeredEventNum) {
            
        }

};

sporterForm.txt

工学院 李四 男 2 123.123 1 3

sportsManagementSystem.cpp

#include <iostream>
#include "sprotsManager.h"
using namespace std;

int main() {
    SportsManager manager;
    int choice = 0;
    cout << "欢迎使用校园运动会管理系统!" << endl;
    while(true) {
        manager.showMenu();
        cin >> choice;
        switch(choice) {
            case 0:
                manager.quit();
                break;

            case 1:
                manager.checkEventInfo();
                break;
            
            case 2:
                manager.registerSporter();
                break;

            case 3:
                manager.deleteSporter();
                break;

            case 4:
                manager.findSporter();
                break;

            case 5:
                manager.modifySporter();
                break;

            case 6:
                manager.checkRegistrationInfo();
                break;

            case 7:
                manager.checkProgram();
                break;

            case 8:
                manager.inputGrade();
                break;

            case 9:
                manager.checkGrade();
                break;

            case 10:
                manager.checkCollegeGrade();
                break;
            
            default:
                system("cls");
                break;
        }
    }
}

sportsManager.cpp

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <algorithm>
#include "event.h"
#include "sprotsManager.h"
using namespace std;


SportsManager::SportsManager() {
    //载入项目安排表
    loadSchedule();
    ifstream iftr;
    iftr.open("sporterForm.txt", ios::in);

    //第一种情况:文件不存在,即没有运动员名单
    if(!iftr.is_open()){
        //运动员人数为0
        sporterNum = 0;
        registerForm = nullptr;
        isEmpty = true;
        iftr.close();
        return;
    }

    //第二种情况:文件存在但为空,既没有运动员报名
    char tmp;
    iftr >> tmp;
    if(!iftr.is_open()){
        //运动员人数为0
        sporterNum = 0;
        registerForm = nullptr;
        isEmpty = true;
        iftr.close();
        return;
    }

    //第三种情况:文件存在且不为空,即已经有人报名了
    isEmpty = false;
    sporterNum = getSporterNum();
    registerForm = new Sporter* [sporterNum];
    loadSporterForm();
}

void SportsManager::showMenu() {
    cout << "---------------------------" << endl;
    cout << "请选择您需要办理的业务:" << endl;
    cout << "0 退出系统" << 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;
}

void SportsManager::quit() {
    cout << "感谢您的使用和支持!" << endl;
    exit(0);
}

void SportsManager::checkEventInfo() {
    cout << setw(20) << left << "项目" << setw(20) << left << "男/女" << setw(20) << left << "地点" << setw(20) << left << "时间" << endl;
    for(auto i : eventForm) {
        cout << setw(20) << left << i.m_name << setw(20) << left << i.m_gender << setw(20) << left << i.m_venue << "第" << i.m_time.substr(0, 2) <<"天 " << i.m_time.substr(2, 12) << endl;
    }
    system("pause");
}

void SportsManager::registerSporter() {
    string college, sporterName, gender;
    cout << "请输入运动员所在学院:";
    cin >> college;
    cout << "请输入运动员的名字:";
    cin >> sporterName;
    cout << "请输入运动员的性别(男/女):";
    cin >> gender;
    //找寻可报名的项目
    if(!findAbledEvent(sporterName, gender))
        //无适合的项目,故停止报名
        return;

    //项目编号
    int eventNum;
    cout << "请输入您要报名的项目的编号:";
    cin >> eventNum;
    
    Sporter *newSporter = new Sporter(college, sporterName, gender, eventNum);

    //开辟新空间
    Sporter **newRegister = new Sporter*[sporterNum + 1];
    //将原空间的运动员报名信息拷贝至新空间
    for(int i = 0; i < sporterNum; ++i){
        newRegister[i] = new Sporter(registerForm[i]->m_college, registerForm[i]->m_name, registerForm[i]->m_gender, registerForm[i]->m_registeredEventNum);
    }
    //更新新的运动员报名信息
    newRegister[sporterNum] = newSporter;
    //释放原有空间
    if(registerForm != nullptr){
        for(int i = 0; i < sporterNum; i++){
            delete registerForm[i];
            registerForm[i] = nullptr;
        }
    }
    delete []registerForm;
    //更新新的空间地址
    registerForm = newRegister;
    //更新运动员数量
    ++sporterNum;
    //文件为空标志赋false
    isEmpty = false;
    saveSporterForm();
    cout << "报名成功!" << endl;
    system("pause");
}

void SportsManager::deleteSporter() {
    int index = findSporter();
    if(index != -1){
        if(eventForm[registerForm[index]->m_registeredEventNum].hasInputGrade) {
            cout << "删除失败,该比赛已结束,如有疑问请联系管理员:186xxxx2222" << endl;
            system("pause");
            return;
        }
        for(int i = index; i < sporterNum; ++i){
            registerForm[i] = registerForm[i+1];
        }
        --sporterNum;
    }
    saveSporterForm();
    cout << "删除成功!" << endl;
    system("pause");
    return;
}

int SportsManager::findSporter() {
    if(isEmpty){
        cout << "运动员报名信息表为空" << endl;
        system("pause");
        return -1;
    }
    string sporterName, eventName;
    cout << "请输入运动员的姓名:";
    cin >> sporterName;
    cout << "请输入运动员所报名的项目名字:";
    cin >> eventName;

    for(int i = 0; i < sporterNum; ++i){
        if(registerForm[i]->m_name == sporterName && eventForm[registerForm[i]->m_registeredEventNum].m_name == eventName){
            cout << setw(20) << left << "学院" << setw(20) << left << "运动员姓名" << setw(20) << left << "男/女" << setw(20) << left << "参赛项目" << setw(20) << left << "地点" << setw(20) << left << "时间" << endl;
            cout << setw(20) << left << registerForm[i]->m_college << setw(20) << left << registerForm[i]->m_name << setw(20) << left << registerForm[i]->m_gender << setw(20) << left << eventForm[registerForm[i]->m_registeredEventNum].m_name << setw(20) << left << eventForm[registerForm[i]->m_registeredEventNum].m_venue << "第" << eventForm[registerForm[i]->m_registeredEventNum].m_time.substr(0, 2) <<"天 " << eventForm[registerForm[i]->m_registeredEventNum].m_time.substr(2, 12) << endl;
            cout << "确认吗?";
            getchar();
            getchar();
            return i; 
        }
    }
    cout << "未找到此报名信息" << endl;
    system("pause");
    return -1;
}

void SportsManager::modifySporter() {
    int index = findSporter();
    if(index != -1){
        if(eventForm[registerForm[index]->m_registeredEventNum].hasInputGrade) {
            cout << "修改失败,该比赛已结束,如有疑问请联系管理员:186xxxx2222" << endl;
            system("pause");
            return;
        }
        string college, sporterName, gender;
        int eventNum;
        cout << "请输入新的学院:";
        cin >> college;
        cout << "请输入新的姓名:";
        cin >> sporterName;
        cout << "请输入新的性别:";
        cin >> gender;

        //寻找可报名的项目
        findAbledEvent(sporterName, gender);
        cout << "请输入您要报名的新的运动项目编号:" << endl;
        cin >> eventNum;
        registerForm[index]->m_college = college;
        registerForm[index]->m_name = sporterName;
        registerForm[index]->m_gender = gender;
        registerForm[index]->m_registeredEventNum = eventNum;
        saveSporterForm();
        cout << "修改成功!" << endl;
        system("pause");
        return;
    }
}

void SportsManager::checkRegistrationInfo() {
    int num = findEvent();
    //未找到
    if(num == -1) 
        return;
    //找到
    cout << eventForm[num].m_name << '(' << eventForm[num].m_gender << ')' << " 时间:" <<  "第" << eventForm[num].m_time.substr(0, 2) <<"天" << eventForm[num].m_time.substr(2, 12) << " 地点:" << eventForm[num].m_venue << endl;
    int cnt = 0;
    for(int i = 0; i < sporterNum; ++i) {
        if(registerForm[i]->m_registeredEventNum == num) {
            cout << registerForm[i]->m_college << ' ' << registerForm[i]->m_name << ' ' << registerForm[i]->m_gender << endl;
            ++cnt;
        }
    }
    cout << "报名此项目的人总计:" << cnt << "(人)" << endl;
    system("pause");
    return ;
}

void SportsManager::checkProgram() {
    ifstream iftr;
    iftr.open("program.txt", ios::in);
    if (iftr.is_open()) { // 或者if (in_file)
        cout << "Open File Successfully" << endl;
        string line;
        while (getline(iftr, line)) {
            cout << line << endl;
        }
    }
    else {
        cout << "Cannot Open File: " << "program.txt" << endl;
    }
    iftr.close();
    //创建一个string类型的数组用来存放所有报名运动员的名字(有重复的)
    vector<string>SporterName;
    for (int i = 0; i < sporterNum; ++i) {
        //存入vector
        SporterName.push_back(registerForm[i]->m_name);
    }
    //进行数组去重
    sort(SporterName.begin(), SporterName.end());
    SporterName.erase(unique(SporterName.begin(), SporterName.end()), SporterName.end());
    cout << endl;
    //输出去重后的数组
    cout << "报名的运动员如下:" << endl;
    for (int i = 0; i < SporterName.size(); i++)
    {
        if(i < SporterName.size()-1){
            cout << SporterName[i] << ",";
        }
        else{
            cout << SporterName[i];
        }
    }
    cout << endl;
    system("pause");
}

void SportsManager::inputGrade() {
    int num = findEvent();
    if(num == -1)
        return;
    //判断项目成绩录入标志是否为真
    if(eventForm[num].hasInputGrade) {
        cout << "该项目已录入成绩" << endl;
        system("pause");
        return;
    }
    //用来判断是否真的有录入成绩(即至少有一个人参加此项目)
    bool  isExit = false;
    cout << eventForm[num].m_name << '(' << eventForm[num].m_gender << ')' << " 时间:" <<  "第" << eventForm[num].m_time.substr(0, 2) <<"天" << eventForm[num].m_time.substr(2, 12) << " 地点:" << eventForm[num].m_venue << endl;
    for(int i = 0; i < sporterNum; ++i) {
        if(registerForm[i]->m_registeredEventNum == num) {
            if(!isExit) {
                isExit = true;
            }
            cout << "请输入" << registerForm[i]->m_name << "的成绩(xxx.xxx):";
            cin >> registerForm[i]->m_grade; 
        }
    }
    if(!isExit) {
        cout << "无人参加此项目!" << endl;
    }else {
        //更新项目已录入成绩的标志
        eventForm[num].hasInputGrade = true;
        caculateRankAndScore(num);
        //保存成绩
        saveSporterForm();
        cout << "该项目成绩录入完毕!" << endl;
    }
   
    system("pause");
}

vector<Sporter*> SportsManager::caculateRankAndScore(int num) {
    //创建一个数组用来存放排好序后的运动员信息
    vector<Sporter*> gradeRank;
    for (int i = 0; i < sporterNum; ++i) {
        if (registerForm[i]->m_registeredEventNum == num) {
            gradeRank.push_back(registerForm[i]);
        }
    }
    //使用sort方法来排序(升序或降序)
    if (eventForm[num].m_sortMark == '>')
        sort(gradeRank.begin(), gradeRank.end(), cmp1);
    else
        sort(gradeRank.begin(), gradeRank.end(), cmp2);

    for (int i = 0; i < gradeRank.size(); i++) {
        //将排好序了的数组的每一个元素与运动员报名表一一匹配
        for (int j = 0; j < sporterNum; ++j)
        {
            //如果报名表内的项目以及姓名匹配的上
            if ((registerForm[j]->m_registeredEventNum == num) && (registerForm[j]->m_name == gradeRank[i]->m_name)) {
                //给与其排名以及得分
                registerForm[j]->m_rank = i + 1;
                if (i + 1 > 3) {
                    registerForm[j]->m_score = 0;
                }
                else {
                    registerForm[j]->m_score = 4 - i - 1;
                }
            }
        }
    }
    //保存数据
    saveSporterForm();
    return gradeRank;
}

void SportsManager::checkGrade() {
    int num = findEvent();
    if(num == -1)
        return;
    //判断项目成绩录入标志是否为假
    if(!eventForm[num].hasInputGrade) {
        cout << "该项目尚未录入成绩" << endl;
        system("pause");
        return;
    }
    vector<Sporter*> gradeRank(caculateRankAndScore(num));
    // 成绩录入标志为真
    if (eventForm[num].hasInputGrade) {
        cout << eventForm[num].m_name << '(' << eventForm[num].m_gender << ')' << " 时间:" << eventForm[num].m_time << " 地点:" << eventForm[num].m_venue << endl;
  
        for (int i = 0; i < gradeRank.size(); i++) {
            if(i < 3)
                cout << "第" << i + 1 << "名 " << gradeRank[i]->m_college << ' ' << gradeRank[i]->m_name << ' ' << gradeRank[i]->m_grade << "得分:" << 3 - i << endl;
            else
                cout << "第" << i + 1 << "名 " << gradeRank[i]->m_college << ' ' << gradeRank[i]->m_name << ' ' << gradeRank[i]->m_grade << "得分:" << 0 << endl;
        }
        cout << "以上" << endl;
        system("pause");
        return;
    }
}


void SportsManager::loadSchedule() {
    ifstream iftr;
    iftr.open("schedule.txt", ios::in);
    string name, gender, time, venue;
    char sortMark;
    //读取硬盘中的项目安排表
    while(iftr >> name >> gender >> venue >> time >> sortMark) {
        Event event(name, gender, venue, time, sortMark);
        eventForm.push_back(event);
    }
    iftr.close();
}

bool SportsManager::findAbledEvent(string sporterName, string gender) {
    //已报名的项目
    vector<int> registeredEventNumList;
    for(int i = 0; i < sporterNum; ++i) {
        if(registerForm[i]->m_name == sporterName) {
            registeredEventNumList.push_back(registerForm[i]->m_registeredEventNum);
        }
    }

    //可报名的项目列表
    vector<int> abledEventNumList;
    //判断与已报名的项目不冲突且符合其它要求的可报名的项目
    if(registeredEventNumList.size() < 3) {//报名项目不能超过三个
        for(int i = 0; i < eventForm.size(); ++i) {
            bool ok = true;
            if(!eventForm[i].hasInputGrade && (gender == eventForm[i].m_gender)) {//项目没有结束(即尚未录入成绩)和性别相符(女子不能参加男子项目)
                for(int j = 0; j < registeredEventNumList.size(); ++j) {
                    //判断与已报的项目是否有时间冲突
                    if(eventForm[i].m_time == eventForm[registeredEventNumList[j]].m_time) {
                        ok = false;
                        break;
                    }
                }
                if(ok)
                    abledEventNumList.push_back(i);
            }
        }
    }

    //一个可以报名的项目都没有
    if(abledEventNumList.size() == 0) {
        cout << "Sorry, 您报名的项目太多(按照学校规定,一个运动员最多只能报名三个项目)或因时间冲突已经没有适合您的项目了,真的非常抱歉" << endl;
        system("pause");
        return false;
    }
    cout << "您可以报名的项目有:" << endl;
    cout << setw(20) << left << "编号" << setw(20) << left << "名称" << setw(20) << left << "地点" << "时间" << endl;
    for(auto i : abledEventNumList) {
        cout << setw(20) << left << i << setw(20) << left << eventForm[i].m_name << setw(20) << left << eventForm[i].m_venue << "第" << eventForm[i].m_time.substr(0, 2) <<"天 " << eventForm[i].m_time.substr(2, 12) << endl;
    }
    return true;
}

int SportsManager::findEvent() {
    string eventName, gender;
    cout << "请输入需要选择的项目名称:";
    cin >> eventName;
    cout << "请选择男子组或女子组(男/女):";
    cin >> gender;
    int num = -1;
    //找寻项目在项目表中的位置
    for(int i = 0; i < eventForm.size(); ++i) {
        if(eventForm[i].m_name == eventName && eventForm[i].m_gender == gender) 
            num = i;
    }
    if(num == -1) {
        cout << "本届运动会无此项目" << endl;
        system("pause");
    }
    return num;
}

int SportsManager::getSporterNum() {
    ifstream iftr;
    iftr.open("sporterForm.txt", ios::in);
    int num = 0;
    string college, name, gender, grade;
    int registeredEventNum, rank, score;
    //文件有多少行就有多少条报名信息
    while(iftr >> college >> name >> gender >> registeredEventNum >> grade >> rank >> score) {
        ++num;
    }
    return num;
}

void SportsManager::loadSporterForm() {
    ifstream iftr;
    iftr.open("sporterForm.txt", ios::in);
    int cnt = 0;
    string college, name, gender, grade;
    int registeredEventNum, rank, score;
    //读取硬盘即txt文件中的已存的报名表信息
    while(iftr >> college >> name >> gender >> registeredEventNum >> grade >> rank >> score){
        registerForm[cnt] = new Sporter(college, name, gender, registeredEventNum, grade, rank, score);
        if(grade != "无" && !eventForm[registeredEventNum].hasInputGrade)//如果已经有成绩了,就将录入成绩标志赋为true
            eventForm[registeredEventNum].hasInputGrade = true;

        cnt++;
    }
    iftr.close();
}

void SportsManager::saveSporterForm() {
    ofstream oftr;
    oftr.open("sporterForm.txt", ios::out);
    //保存报名信息表和成绩
    for(int i = 0; i < sporterNum; ++i){
        oftr << registerForm[i]->m_college << ' ' << registerForm[i]->m_name << ' ' << registerForm[i]->m_gender << ' ' << registerForm[i]->m_registeredEventNum << ' ' << registerForm[i]->m_grade << ' ' << registerForm[i]->m_rank << ' ' << registerForm[i]->m_score << endl;
    }
    oftr.close();
}

void SportsManager::checkCollegeGrade() {
    vector<string> CollegeGrade;
    for (int i = 0; i < sporterNum; ++i) {
        CollegeGrade.push_back(registerForm[i]->m_college);
    }
    sort(CollegeGrade.begin(), CollegeGrade.end());
    CollegeGrade.erase(unique(CollegeGrade.begin(), CollegeGrade.end()), CollegeGrade.end());
    int n = CollegeGrade.size();
    vector<int> collegeScore(n, 0);
    cout << "以下是各学院的得分情况" << endl;
    //输出去重后的数组
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < sporterNum; ++j) {
            if (registerForm[j]->m_college == CollegeGrade[i]) {
                if(eventForm[registerForm[j]->m_registeredEventNum].hasInputGrade)      collegeScore[i] += registerForm[j]->m_score;
            }
        }

        cout << "学院:" << CollegeGrade[i] << " " << "总得分:" << collegeScore[i] << endl;
    }
    system("pause");
}

SportsManager::~SportsManager() {
    //释放开辟的堆空间
    if(registerForm != nullptr){
        for(int i = 0; i < sporterNum; i++){
            delete registerForm[i];
            registerForm[i] = nullptr;
        }
    }
    delete []registerForm;
    registerForm = nullptr;
}



bool cmp1(Sporter *a, Sporter *b) {
        return a->m_grade > b->m_grade;
}

bool cmp2(Sporter *a, Sporter *b) {
        return a->m_grade < b->m_grade;
}

sprotsManager.h

#pragma once
#include "sporter.h"
#include <vector>

//管理类
class SportsManager{
public:
    //构造函数
    SportsManager();

    //操作页面菜单
    void showMenu();

    //退出程序
    void quit();

    //查看比赛项目信息
    void checkEventInfo();

    //运动员报名登记
    void registerSporter();

    //删除运动员报名信息
    void deleteSporter();

    //查找运动员报名信息
    int findSporter();

    //修改运动员报名信息
    void modifySporter();

    //查看运动员报名信息
    void checkRegistrationInfo();

    //查看秩序册
    void checkProgram();

    //比赛成绩录入
    void inputGrade();

    //比赛成绩查询
    void checkGrade();
    
    //查看各学院的得分
    void checkCollegeGrade();

    //析构函数
    ~SportsManager();
    
private:
    //运动员报名信息数量
    int sporterNum;
    //开辟堆保存运动员信息
    Sporter **registerForm;
    //判断运动员信息表是否为空的标志
    bool isEmpty;
    //运动会项目时间安排表
    vector<Event> eventForm;

    //载入项目计划表
    void loadSchedule();

    //查询可以报名的项目
    bool findAbledEvent(string, string);

    //查找项目的索引
    int findEvent();

    //计算排名和得分
    vector<Sporter *> caculateRankAndScore(int);

    //获取已存的运动员报名表中的运动员数量
    int getSporterNum();

    //将已存的运动员报名表读入内存中
    void loadSporterForm();



    //将内存中的运动员数据保存到硬盘中
    void saveSporterForm();
};

bool cmp1(Sporter *, Sporter *);

bool cmp2(Sporter *, Sporter *);

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2023年12月21日
下一篇 2023年12月21日

相关推荐