一、关于这个管理系统所要实现的功能
1、12名种子选手进行轮次比赛。
2、共进行两轮比赛,第一轮分两组进行演讲比赛经过评委打分决出下一轮比赛的选手,第二轮总决赛选出前三名选手(演讲顺序依抽签为准!)(10个评委进行打分-去掉最高分和最低分算取平均分!)
3、将比赛记录存储到文件中,可随时查看比赛记录。
二、关于这个管理系统所要用到的C++的知识
这个案例主要是为了学习容器的知识用到了vector、map、multimap、dequed和一些插入、排序、求和的算法知识

三、关于这个管理系统的执行逻辑
1、先建立一个管理者的类-管理者是这个系统的操控者主宰着这场游戏的生死!!!以管理者的角度看,我主宰着这场游戏,一切都在我的掌控之中!
2、管理者类中就应该创建出要实现的成员功能函数和要表达的成员属性。
3、将所要实现的功能函数封装好后在主函数中通过管理者对象进行调用。

四、代码-
1、演讲者类-头文件

#pragma once
#include<iostream>
using namespace std;class Speaker
{public:string m_Name;//姓名double m_Score[2];//分数,最多记录两轮的得分
};//一般成员属性是设置为私有属性
//需要提供get/set的方法进行修改

2、管理者类-头文件

#pragma once
#include<iostream>
using namespace std;
#include<vector>
#include<map>
#include"Speaker.h"
#include<algorithm>
#include<deque>
#include<functional>
#include<numeric>
#include<fstream>
#include<ctime>//设计演讲比赛的管理类
//功能描述
/*1、提供菜单界面与用户交互
* 2、对演讲比赛流程进行控制
* 3、与文件的读写交互
*/
//管理者类中包含了所有要执行的操作的成员函数-和要表达的成员属性
class SpeechManager
{public://构造函数SpeechManager();//展示菜单void show_Menu();//初始化属性void initSpeech();//退出系统void exitSystem();//初始化创建12名选手void creatSpeaker();//开始比赛-比赛控制流程void startSpeech();//这个函数用来控制整个比赛的流程//开始抽签void speechDraw();//正式比赛void speechContest();//显示比赛结果void showScore();//保存记录void saveRecord();//读取记录分数void loadRecord();//判断文件为空的标志bool fileIsEmpty;//显示往届得分void showRecord();//清空记录void clearRecord();//析构函数~SpeechManager();//在头文件里面只写函数的声明不写实现//构造函数和析构函数,如果自己不写,编译器也会给我们写上//成员属性//保存第一轮比赛选手编号容器vector<int>v1;//第一轮晋级参加第二轮比赛选手编号的容器vector<int>v2;//胜出前三名选手编号容器vector<int>vVivtory;//存放编号以及对应具体选手容器map<int, Speaker>m_Speaker;//这个容器哈哈哈-里面编号,选手姓名-分数它都有//往届记录map<int, vector<string>>m_Record;//key代表第几届,value记录所有信息//记录比赛轮次int m_Index;
};

2.2、管理者类-源文件

#include"speechManager.h"//构造函数
SpeechManager::SpeechManager()
{//初始化容器和属性的函数this->initSpeech();//创建选手this->creatSpeaker();//获取往届记录this->loadRecord();        //这条就是出现头行文件不存在的情况的原因}//菜单功能
void SpeechManager::  show_Menu()
{cout << "------------------------------------" << endl;cout << "----------欢迎参加演讲比赛----------" << endl;cout << "----------1、开始演讲比赛-----------" << endl;cout << "----------2、查看往届记录-----------" << endl;cout << "----------3、清空比赛记录-----------" << endl;cout << "----------0、退出比赛程序-----------" << endl;cout << "------------------------------------" << endl;cout << endl;
}//初始化属性
void SpeechManager::initSpeech()
{//保证容器都置空this->v1.clear();this->v2.clear();this->vVivtory.clear();this->m_Speaker.clear();//初始化比赛轮次this->m_Index = 1;//初始化记录容器this->m_Record.clear();
}//初始化创建12名选手
void SpeechManager::creatSpeaker()
{string nameSeed = "ABCDEFGHIJKL";//创建名称种子for (int i = 0; i < nameSeed.size(); i++){string name = "选手";//通过循环给每个选手进行标号name += nameSeed[i];Speaker sp;//通过选手类创建选手对象sp.m_Name = name;//然后给每个创建出来的选手进行命名///for (int i = 0; i < 2; i++){sp.m_Score[i] = 0;//将可以存放两轮分数的m_Score都赋初值0}/////12名选手编号,放到v1容器中this->v1.push_back(i + 10001);//选手编号以及对应的选手存放到map容器中this->m_Speaker.insert(make_pair(i + 10001, sp));}}//开始抽签
void SpeechManager::speechDraw()
{cout << "第" << this->m_Index << "轮比赛选手正在抽签" << endl;cout << "----------------------------------------" << endl;cout << "抽签后的演讲顺序如下:" << endl;//区别是第几轮比赛通过一个判断语句if (this->m_Index == 1){//第一轮比赛抽签random_shuffle(v1.begin(),v1.end());//STL 中的函数 random_shuffle() 用来对一个元素序列进行重新排序(随机的)-头文件是#include <algorithm>//这里就类似于摇号箱一样将里面的内容打乱//这里通过vector迭代器遍历抽签后的出场编号并打印for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++){cout << *it << " ";}cout << endl;}else{//第二轮比赛抽签random_shuffle(v2.begin(), v2.end());for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++){cout << *it << " ";}cout << endl;}system("pause");cout << endl;
}//抽签后正式比赛
void SpeechManager::speechContest()
{cout << "------第" << this->m_Index << "轮正式比赛开始:-------" << endl;multimap<double, int, greater<double>>groupScore;//临时容器,保存key-分数 value-选手编号//multimap容器允许出现重复的值-greater<double>为降序排列int num = 0;//记录人员数,6个为1组vector<int>v_Src;//比赛的人员容器-用来存储比赛中选手的容器if (this->m_Index == 1){v_Src = v1;//如果是第一轮比赛就将容器1里面的数据给比赛专用的容器}else{v_Src = v2;}//遍历v_Src容器里所有参赛选手for (vector<int>::iterator it = v_Src.begin(); it != v_Src.end(); it++){num++;//记录选手个数//评委打分deque<double>d; //评委打分的容器-deque双向开口可进可出的容器 -对头部的插入删除速度快for (int i = 0; i < 10; i++){double score = (rand() % 41 + 60) / 1.f;//60~100//这样可以创建出小数//cout << score << " ";//具体的得分-测试代码d.push_back(score);//然后通过尾插法将评委的打分存储到deque的容器中}sort(d.begin(), d.end(), greater<double>());//降序排列d.pop_front();//去掉最高分d.pop_back();//去掉最低分double sum = accumulate(d.begin(), d.end(), 0.0f);//获取总分//第三个参数是起始累加值-头文件是#include<numeric>double avg = sum / (double)d.size();//获取平均分-这里用到了一个强制转换//打印平均分-测试代码//cout << "编号:" << *it << "  姓名:" << this->m_Speaker[*it].m_Name << "  获取平均分:" << avg << endl;//将得到的平均分放到正在参赛选手的容器中-对应存放选手得分的记录this->m_Speaker[*it].m_Score[this->m_Index - 1] = avg;//double m_Score[2];//分数,最多记录两轮的得分//将参加比赛的选手的得分和编号放到临时的groupScore容器中groupScore.insert(make_pair(avg,*it));//key是得分,value是具体选手的编号//每6人取出前三名-每轮6人制比赛if (num % 6 == 0){cout << "第" << num / 6 << "小组比赛名次: " << endl;//通过迭代器遍历临时multimap容器groupScore中的选手信息-并打印信息for (multimap<double, int, greater<double>>::iterator it = groupScore.begin(); it != groupScore.end(); it++){//cout << "编号:" << it->second << "  姓名:" << this->m_Speaker[it->second].m_Name << "  成绩:" <<this->m_Speaker[it->second].m_Score[this->m_Index-1] << endl;}
////取走前三名-在临时存放选手信息的容器中(这个容器里的信息是采用降序排列的)截取前三名几位老大老二老三int count = 0;for (multimap<double, int, greater<double>>::iterator it = groupScore.begin(); it != groupScore.end()&&count<3; count++, it++){if (this->m_Index == 1){    //如果是第一轮就将选手的编号放到容器2中等待第二轮的比赛v2.push_back((*it).second);}else{//如果不是第一轮的比赛即为第二轮比赛-截取到前三名以后即为最后比赛的结果-存放到胜利的容器中vVivtory.push_back((*it).second);}}groupScore.clear();//举行完一次比赛以后要及时的将临时容器里面的数据清空等待下一次比赛的运用cout << endl;}}cout << "--------第<<"<<this->m_Index<<">>轮比赛完毕-----"<<endl; //到这里已经遍历了v_Src容器里所有参赛选手的信息-即为完成了一次比赛system("pause");
}//显示比赛结果
void  SpeechManager::showScore()
{cout << "------第" << this->m_Index << "轮晋级选手信息如下:-------" << endl;vector<int>v;//funk-又一个容器啊!!!!!if (this->m_Index == 1){v = v2;//如果是第一轮比赛-那么容器2中存放的是晋级选手的信息-这样就将容器2里面的信息赋值给容器v}else{v = vVivtory;//如果不是第一轮比赛即为第二轮比赛-则vVivtory容器中存放了最后前三名选手的信息-将其赋值给容器v}//通过迭代器遍历打印晋级选手的信息for (vector<int>::iterator it = v.begin(); it != v.end(); it++){cout << "编号:" << *it << "  姓名:" << m_Speaker[*it].m_Name << "  得分:"<< m_Speaker[*it].m_Score[this->m_Index - 1] << endl;}cout << endl;system("pause");system("cls");
this->show_Menu();
}//保存记录
void SpeechManager::saveRecord()
{ofstream ofs;ofs.open("speech.csv", ios::out | ios::app);//用输出方式打开文件---写文件(append追加的写文件)//将每个数据写入到文件中-这里只写决赛前三名选手的信息-for (vector<int>::iterator it = vVivtory.begin(); it != vVivtory.end(); it++){ofs << *it << "," << m_Speaker[*it].m_Score[1] << ",";//ofs和cout类似,ofs是将数据显示在了文件里面,cout是将数据显示到了编译器上面}//这里用逗号是为了在读数据的时候方便!!!!!目前我是这样理解的ofs << endl;//文件里面换行//关闭文件ofs.close();cout << "记录已经保存" << endl;//有记录了,文件不为空-更改文件为不为空的状态this->fileIsEmpty = false;//判断文件是否为空}//读取记录分数
void SpeechManager::loadRecord()
{ifstream ifs("speech.csv", ios::in);//输入流对象,读取文件//1、文件不存在的情况if (!ifs.is_open())//如果打开失败{this->fileIsEmpty = true;//告诉编译器,文件是空的//cout << "文件不存在!" << endl;ifs.close();return;//这个直接返回是啥意思呢!!!!!!目前还不太清楚!!!}//2、文件清空的情况char ch;ifs >> ch;//自动将文件中的字符输入-加入直接是输入的是”文件尾为空“-即为空文件if (ifs.eof())//判断是否读到了文件尾{//cout << "文件为空!" << endl;this->fileIsEmpty = true;ifs.close();return;}//3、文件不为空this->fileIsEmpty = false;//文件不为空ifs.putback(ch);//将上面读取的单个字符放回去-???为什么要放回呢?????///string data;//创建了一个data的对象//while (ifs >> data)//{  //这段是测试代码,下面的代码是对这段代码进行解析//   cout << data << endl;// //10002,86.675,10009,81.3,10007,78.55,//}int index = 1;//第几届的下标while (ifs >> data){//存放6个字符串信息的容器vector<string>v;//----------int pos = -1;//查到","位置的变量int start = 0;//每次进行查找的起始位置//一个循环进行轮换的寻找while (true){pos = data.find(",", start);//从start开始查找”,”找到后返回其位置信息//1、没有找到的情况if (pos == -1){break;//找不到break返回}//2、找到的情况//查找的位置-起始位置string tmp = data.substr(start, pos - start);//找到了,进行分割//参数1-起始位置,参数2-截取长度//存放6个string的字符串-前三名的信息v.push_back(tmp);//cout << tmp << endl;start = pos + 1;//更改起始位置}/??????这里为什么要向m_Record容器中添加数据呢?////m_Record添加数据this->m_Record.insert(make_pair(index, v));index++;///}ifs.close();///for (map<int, vector<string>>::iterator it = m_Record.begin(); it != m_Record.end(); it++){//cout <<"第<<"<< it->first << ">>冠军编号:" << it->second[0] << " 分数:" << it->second[1] << endl;}///}//显示往届得分
void SpeechManager::showRecord()
{if (this->fileIsEmpty){cout << "文件不存在或记录为空!" << endl;}else{for (map<int, vector<string>>::iterator it = m_Record.begin(); it != m_Record.end(); it++){cout << "第<<" << it->first << ">>届冠军:编号:" << it->second[0] << " 得分:" << it->second[1] <<"     亚军:编号:" << it->second[2] << " 得分:" << it->second[3] <<"     季军:编号:" << it->second[4] << " 得分:" << it->second[5] << endl; //存了6个字符串所以是0-1-2-3-4-5}//     for (int i = 0; i < this->m_Record.size(); i++)//{//这里中括号访问会出问题,不知道为什么//    //以中扩号的方式访问数据// cout << "第" << i + 1 << "届";//   cout << "冠军编号:" << this->m_Record[i][0] << "得分:" << this->m_Record[i][1] << " ";//  cout << "亚军编号:" << this->m_Record[i][2] << "得分:" << this->m_Record[i][3] << " ";//  cout << "季军编号:" << this->m_Record[i][4] << "得分:" << this->m_Record[i][5] << endl;//}}system("pause");system("cls");
}//清空记录
void SpeechManager:: clearRecord()
{cout << "确认清空?" << endl;cout << "1、确认" << endl;cout << "2、返回" << endl;int select = 0;cin >> select;if (select ==1){//打开模式ios::trunc 如果存在删除文件重新创建ofstream ofs("speech.csv", ios::trunc);//trunc:将先前的文件内容移除(Remove)-ate:打开文件之后令读写位置移至文件尾端(at end)ofs.close();//初始化属性this->initSpeech();//创建选手this->creatSpeaker();//获取往届记录this->loadRecord();cout << "清空成功!" << endl;}system("pause");system("cls");
}//开始比赛-比赛控制流程
void SpeechManager::startSpeech()
{//第一轮比赛//1、抽签this->speechDraw();//2、比赛this->speechContest();//3、显示晋级结果this->showScore();//第二轮比赛this->m_Index++;//1、抽签this->speechDraw();//2、比赛this->speechContest();//3、显示最终结果this->showScore();//4、保存分数到文件中this->saveRecord();//到这里所有的比赛已经结束了!//重置比赛-这里之前的数据已经存入文件,需要将容器中的数据清空//初始化属性this->initSpeech();//创建选手this->creatSpeaker();//这三个函数如何封装在一个函数中//获取往届记录this->loadRecord();cout << "本届比赛完毕!" << endl;system("pause");system("cls");}//退出系统
void SpeechManager::exitSystem()
{cout << "欢迎下次使用!" << endl;system("pause");exit(0);
}//析构函数
SpeechManager::~SpeechManager()//加上作用域是成员函数
{}

3、主函数

#include<iostream>
using namespace std;
#include"speechManager.h"int main()
{//随机数的种子,这样编译器每次运行出来的数据就会不一样//创建管理类的对象-通过管理者类创建出来管理者对象来调用管理者类里面的成员函数SpeechManager sm;测试12名选手的创建//map容器不允许储存相同的值for (map<int, Speaker>::iterator it = sm.m_Speaker.begin(); it != sm.m_Speaker.end(); it++){  cout << "选手编号:" << it->first << "姓名:" << it->second.m_Name << "分数:" << it->second.m_Score << endl;}int choice = 0;//用于接受用户的输入while (true)//创建一个无限的循环,当程序启动时,将会一直在这个循环中进行知道操作退出{//1、显示菜单-通过管理者对象来调用显示菜单的成员函数sm.show_Menu();cout << "请输入你的选择:" << endl;cin >> choice;switch (choice){//开始比赛case 1: sm.startSpeech();//调用开始比赛的成员函数// system("cls");break;//查看往届比赛记录case 2:sm.showRecord();break;//清空比赛记录case 3:sm.clearRecord();break;//退出系统case 0:sm.exitSystem();break;default://  system("cls");break;}}//system("pause");return 0;
}

以上便是此次系统的所有内容-代码中已经做了详细的注解!!!

基于STL的演讲比赛流程管理系统相关推荐

  1. c++小项目:基于STL的演讲比赛流程管理系统

    一.项目目的 运用c++实现一个基于STL的演讲比赛流程管理系统. 比赛方式 共两轮,第一轮为分组淘汰赛,第二轮为决赛,共有十名评委,打分方式为去掉最高分和最低分的平均分为基准 第一轮共两组,每组六人 ...

  2. C++基于STL的演讲比赛流程管理系统

    目录 介绍 speaker.h speechManager.h speechManager.cpp 演讲比赛流程管理系统.cpp 介绍 学校举行一场演讲比赛,共有12个人参加.比宴共两轮,第一轮为淘汰 ...

  3. C++阶段06笔记01【基于STL的演讲比赛流程管理系统】

    C++匠心之作-从0到1入门学编程[视频+课件+笔记+源码] 目录 1.演讲比赛程序需求 1.1.比赛规则 1.2.程序功能 1.3.程序效果图 2.项目创建 2.1.创建项目 2.2.添加文件 3. ...

  4. 基于STL的演讲比赛流程管理系统(C++STL实战)

    目录 1.演讲比赛程序需求 1.1比赛规则 1.2程序功能 2.项目创建 3.创建管理类 3.1创建文件 3.2头文件实现 3.3源文件实现 4.菜单功能 4.1添加成员函数 4.2菜单功能实现 4. ...

  5. 黑马程序员:C++案例(基于STL实现演讲比赛流程管理系统)

    1.1.比赛规则 学校举行一场演讲比赛,共有12个人参加,比赛共两轮,第一轮为淘汰赛,第二轮为决赛 每名选手都有对应的编号,如10001~10012 比赛方式:分组比赛,每组6个人: 第一轮分为两个小 ...

  6. C++提高编程(六)—— 案例 :演讲比赛流程管理系统(上)

    C++系列内容的学习目录 → \rightarrow →C++学习系列内容汇总. 1. 演讲比赛程序需求 1.1 比赛规则 1.2 程序功能 1.3 程序效果图 2. 创建项目 3. 创建管理类 3. ...

  7. 演讲比赛流程管理系统C++

    参考B站黑马视频 演讲比赛流程管理系统 1.1.比赛规则 学校举行演讲比赛,共有12人参加.比赛共两轮,第一轮为淘汰赛,第二轮为决赛 每名选手都有对应的编号,如10001 ~ 10012 比赛方式:分 ...

  8. C++入门——演讲比赛流程管理系统

    参考链接 https://www.bilibili.com/video/BV1et411b73Z?p=264 演讲比赛流程管理系统 演讲比赛程序需求 比赛规则 学校举行一场演讲比赛,共有12个人参加. ...

  9. 【带你敲】演讲比赛流程管理系统

    CSDN话题挑战赛第2期 参赛话题:学习笔记 1. 演讲比赛程序需求 1.1 比赛规则 学校举行一场演讲比赛,共有12个人参加.比赛共两轮,第一轮为淘汰赛,第二轮为决赛. 比赛方式:分组比赛,每组6个 ...

最新文章

  1. php正则表达式匹配img中任意属性的方法
  2. 吐血整理 | 肝翻 Linux 进程调度所有知识点|中奖揭晓
  3. 给mysql 授权 命令_mysql中授权命令grant用法详解:
  4. Android——内存调试
  5. 盘点:12个超炫数据可视化工具
  6. 【计算机网络知识扫盲】十二、★Net命令详解☆
  7. oracle中both,ORACLE:scope=both|memery|spfile
  8. 安装Kaggle库,常见问题上之目录中没有.kaggle文件夹(附解决办法!)
  9. 网上书城|基于PHP实现网上书店商城藉项目
  10. 镁光256Gb NAND Flash芯片介绍
  11. 计算机管理找不到新安装的系统,我的电脑开机显示找不到启动设备,请在硬盘上安装操作系统怎么办?开...
  12. 【C++】Lambda 表达式详解
  13. HDU 2565 放大的X【图形】
  14. win10pro不够pro,win10专业工作站版本才是真的牛。
  15. Mysql错误编码和解释表
  16. 矿大计算机学院辅导员,2019届矿大毕业生,辅导员有话对你说!(二)
  17. 这帮死磕技术的理工男造了一支笔
  18. 小程序接入流量主、banner广告、激励广告
  19. LANG和NLS_LANG的区别
  20. Kerberos安装及使用3(Kerberos基本管理实践)

热门文章

  1. 通过文献计量学助您发表高影响因子论文—基于Citespace和vosviewer文献计量学可视化SCI论文高效写作方法
  2. android 实现Home键和Back键的功能
  3. PyQt5之QDateTimeEdit编辑日期时间
  4. DL/T645-2007电表协议 数据域DATA注意事项
  5. HCIP2--ISIS
  6. 图像卷积的常见误区与个人思考
  7. 工业物联网的价值有哪些
  8. 米的换算单位和公式_米的单位换算公式大全(长度单位大全表)
  9. 使用cpolar建立固定的SSH隧道
  10. UG编程-适合新手的详细讲解