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

news2024/11/16 11:43:34

这是一个完整的项目,若有需要整个项目的压缩包(源代码、文档、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 *);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/707756.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java 实现支付宝支付、退款、订单查询

最在开发一款APP&#xff0c;需要实现支付宝支付&#xff0c;记录一下实现过程 流程整体交互图如下所示 一、引入pom依赖 <dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.0.3<…

【Java可执行命令】(八)JWS应用程序启动工具 javaws:深入解析Java Web Start应用程序的启动工具javaws ~

Java可执行命令之javaws 1️⃣ 概念&#x1f50d;JNLP (Java Network Launch Protocol) &#xff1f; 2️⃣ 优势3️⃣ 使用3.1 语法3.1.1 运行选项&#xff1a;-Xnosplash3.1.2 运行选项&#xff1a;-wait3.1.3 控制选项&#xff1a;-import [导入选项] < jnlp-file> 4️…

IDEA中删除某个模块后在创建同名模块显示已存在 的解决方案

IDEA中删除某个模块后在创建同名模块显示已存在 的解决方案 出现的问题复现解决方案成功添加后可能会出现的问题 出现的问题复现 前提是你认为已经删干净了&#xff0c;因为删除模块得删除两次才能从本地的文件夹中删除。 解决方案 右击项目名 找到 这个玩意儿&#xff0c;点…

MySQL不常用但非常实用的函数在项目中的应用

MySQL内置了不少函数&#xff0c;利用这些函数可以很好地在进行数据查询时候&#xff0c;进行数据处理&#xff0c;如果要查看MySQL所有的内置函数&#xff0c;可以在官网的文档中&#xff1a;Built-In Function and Operator Reference 有很详细的表格&#xff0c;列举了所有…

代码随想录二刷day39 |动态规划 之 62.不同路径 63. 不同路径

day39 62.不同路径确定dp数组&#xff08;dp table&#xff09;以及下标的含义确定递推公式dp数组的初始化确定遍历顺序举例推导dp数组 63. 不同路径 II确定dp数组&#xff08;dp table&#xff09;以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组 62.不…

模仿QQ之右键菜单

参考&#xff1a;QT多级菜单 - 知乎 (zhihu.com) 运行效果图&#xff1a; 关键代码&#xff1a; void personMenu::contextMenuEvent(QContextMenuEvent *event) {//我完全可以写出一个代码生成器来把这些代码生成出来。parentnew QMenu(this);parent->addAction(QIcon(…

C++ 多态详解附图与代码

一、多态 1.1 什么是多态 多态是面向对象编程中的一个重要概念&#xff0c;它允许在不同类型的对象上执行相同的操作&#xff0c;并根据对象的实际类型来决定具体执行哪个操作。通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是去完成某个行为&#xff0c;当不同的对象…

2019年全国硕士研究生入学统一考试管理类专业学位联考逻辑试题——纯享题目版

&#x1f3e0;个人主页&#xff1a;fo安方的博客✨ &#x1f482;个人简历&#xff1a;大家好&#xff0c;我是fo安方&#xff0c;考取过HCIE Cloud Computing、CCIE Security、CISP等证书。&#x1f433; &#x1f495;兴趣爱好&#xff1a;b站天天刷&#xff0c;题目常常看&a…

【排序算法】堆排序

堆与一维数组 建立堆与一维数组的联系 堆排序并不是直接对堆节点Node类型排序&#xff0c;而是通过建立索引之间的关系&#xff0c;对一维数组排序。 称之为堆排序&#xff0c;是因为节点索引值之间的关系与完全二叉树的非常类似&#xff0c;而树又称堆。 设根节点为i&#xff…

【C#】委托、匿名方法、Lambda表达式和事件

【C#】委托、匿名方法、Lambda表达式和事件 委托 什么是委托&#xff1f; 委托和类一样&#xff0c;是用户自定义类型&#xff0c;是方法&#xff08;函数&#xff09;的抽象。通俗讲&#xff0c;委托就是 自定义类型的方法&#xff08;函数&#xff09;的代表。 声明委托 …

HTML+CSS+JavaScript华为主页

样式&#xff1a; HTMLCSSJavaScript仿华为首页 HTML: <!DOCTYPE html> <html><head><meta charset"utf-8"><link rel"stylesheet" type"text/css" href"Homepage.css"/><script type"text/ja…

NextJs下浅尝Prisma+Sqlite+逆向生成数据模型

1.安装prisma npm install prisma/client 2.创建schema.prisma npx prisma init 执行完命令后创建文件目录如下&#xff1a; 3.配置数据库连接 generator client {provider "prisma-client-js" }datasource db {provider "sqlite" //数据库类型 这…

libevent实践07:监听服务器并管理客户端

简介 函数bufferevent_new struct bufferevent * bufferevent_new(evutil_socket_t fd,bufferevent_data_cb readcb, bufferevent_data_cb writecb,bufferevent_event_cb eventcb, void *cbarg) 参数说明&#xff1a; fd:新客户端的文件描述符 readcb&#xff1a;一个函数指…

【Redis的优化】

目录 一、Redis 高可用二、 Redis 持久化2.1、Redis 提供两种方式进行持久化2.2、RDB 持久化1. 触发条件&#xff08;1&#xff09;手动触发&#xff08;2&#xff09;自动触发 2. 执行流程3. 启动时加载 2.3、AOF 持久化1. 开启AOF2. 执行流程(1&#xff09;命令追加(append)(…

深入理解 Linux 物理内存分配全链路实现

目录 内核物理内存分配接口 物理内存分配内核源码实现 内存分配的心脏 __alloc_pages prepare_alloc_pages 内存慢速分配入口 alloc_pages_slowpath 总结 内核物理内存分配接口 在物理内存分配成功的情况下&#xff0c; alloc_pages&#xff0c;alloc_page 函数返回的都是指…

2022最常用密码公布,你的账户安全吗?

密码管理工具 NordPass 公布了 2022 年最常用密码列表&#xff0c;以及破解密码所需的时间。该研究基于对来自 30 个不同国家 / 地区的 3TB 数据库的分析。研究人员将数据分为不同的垂直领域&#xff0c;使得其能够根据国家和性别进行统计分析。今年的研究主要聚焦于文化如何影…

工业软件对于现代制造业的生产效率和质量有何影响?

工业软件在提高现代制造业的生产力和质量方面发挥着至关重要的作用。比如&#xff1a; 流程自动化&#xff1a;工业软件可以实现各种制造流程的自动化&#xff0c;消除手动任务并减少人为错误。自动化通过简化操作、缩短周期时间和提高整体效率来提高生产力。它还可以最大限度地…

vue3和element plus踩坑

1.有说vue版本有两个&#xff0c;但检查之后发现只有一个&#xff0c;且为vue3的版本 2.也有说是因为命名的问题&#xff0c;组件名和页面名一致 最后发现是因为 在main.js里面引入element plus 使用这种use方式会报错&#xff0c;虽然也不知道为什么 import { createApp } …

《计算机系统与网络安全》第十一章 入侵检测与防御技术

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

Dell-Precision5520 电脑 Hackintosh 黑苹果efi引导文件

原文来源于黑果魏叔官网&#xff0c;转载需注明出处。&#xff08;下载请直接百度黑果魏叔&#xff09; 硬件配置 硬件型号驱动情况 主板Dell-Precision5520 处理器Intel Core i7-7820HQ已驱动 内存Micron 2400MHz DDR4 16GB x2已驱动 硬盘Samsung 970EVO 512GB已驱动 显…