各位读者朋友,大家好!本篇文章主要内容是将黑马程序员(C++)的演讲比赛流程管理系统的源代码展现给大家。原码的大部分与黑马程序员老师写的代码一致,我只是对其中的一小部分做了优化,比如用户输入自己的选择不再程序服务范围内,便可以让用户重新选择等等。各位读者朋友如果在阅读过程中发现问题或者有更好的建议,可以在评论区告诉我或者给我留言,我一定第一时间改进,谢谢大家!
1. 演讲比赛程序需求
- 学校举行一场演讲比赛,共有12个人参加。比赛共两轮,第一轮为淘汰赛,第二轮为决赛;
- 每名选手都有对应的编号,如10001~10012;
- 比赛方式:分组比赛,每组6个人;
- 第一轮分为两个小组,整体按照选手编号进行抽签后顺序演讲;
- 十个评委分别给每名选手打分,去除最高分和最低分,求得平均分为本轮选手的成绩;
- 当小组演讲完后,淘汰组内排名最后的三个选手,前三名晋级,进入下一轮的比赛;
- 第二轮为决赛,前三名胜出;
- 每轮比赛过后需要显示晋级选手的信息。
2. 程序功能
- 开始演讲比赛:完成整届比赛的流程,每个比赛阶段需要给用户一个提示,用户按任意键后继续下一个阶段;
- 查看往届记录:查看之前比赛前三名结果,每次比赛都会记录到文件中,文件用. csv后缀名保存;
- 清空比赛记录:将文件中数据清空;
- 退出比赛程序:可以退出当前程序。
3. 代码
3.1 speaker.h
#pragma once
#include<iostream>
using namespace std;
//选手类
class Speaker
{
public:
string m_Name;//参赛选手的姓名
double m_Score[2];//参赛选手的分数,最多有两轮得分
};
3.2 speechManager.h
#pragma once
#include<iostream>
using namespace std;
#include<string>
#include<vector>
#include<map>
#include"speaker.h"
#include<algorithm>
#include<deque>
#include<functional>
#include<numeric>
#include<fstream>
class SpeechManager//演讲管理类
{
public:
SpeechManager();//构造函数
void show_Menu();//展示菜单
void exit_System();//退出系统
void init_Speech();//初始化成员属性的函数
void create_Speaker();//创建12名选手
void start_Speech();//开始比赛(整个比赛流程的控制函数)
void speechDraw();//抽签
void speechContest();//比赛
void showScore();//显示得分
void saveRecord();//将最终前3名的得分保存到文件中
void loadRecord();//读取记录
void show_Record();//显示往届记录
void clear_Record();//清空文件
~SpeechManager();//析构函数
//成员属性
vector<int>v1;//保存第一轮选手的编号的容器
vector<int>v2;//保存第二轮选手的编号的容器
vector<int>vVictory;//保存最终前三名选手的编号的容器
map<int, Speaker>m_Speaker;//存放编号以及对应的具体选手的容器
int m_Index;//记录比赛轮次
bool fileIsEmpty;//判断文件是否为空
map<int, vector<string>>m_Record;//存放往届记录的容器
};
3.3 speechManager.cpp
#include"speechManager.h"
//构造函数
SpeechManager::SpeechManager()
{
this->init_Speech();//初始化成员属性
this->create_Speaker();//创建12名选手
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::exit_System()
{
cout << "欢迎下次使用!" << endl;
system("pause");
exit(0);
}
//初始化成员属性的函数
void SpeechManager::init_Speech()
{
//将容器初始化为空
this->v1.clear();
this->v2.clear();
this->vVictory.clear();
this->m_Speaker.clear();
//初始化比赛轮次
this->m_Index = 1;
//将存放记录的容器清空
this->m_Record.clear();
}
//创建12名选手
void SpeechManager::create_Speaker()
{
string nameSeed = "ABCDEFGHIJKL";
for (int i = 0; i < nameSeed.size(); i++)
{
string name = "选手";
name += nameSeed[i];
Speaker sp;//创建具体的选手
sp.m_Name = name;
for (int j = 0; j < 2; j++)
{
sp.m_Score[j] = 0;
}
this->v1.push_back(10001 + i);//创建选手编号并且放到v1容器中
this->m_Speaker.insert(make_pair(10001 + i, sp));//创建编号以及对应的具体选手,放到容器中
}
}
//开始比赛(整个比赛流程的控制函数)
void SpeechManager::start_Speech()
{
//开始第1轮比赛
this->speechDraw();//1、抽签
this->speechContest();//2、比赛
this->showScore();//3、显示晋级结果
//开始第2轮比赛
this->m_Index++;
this->speechDraw();//1、抽签
this->speechContest();//2、比赛
this->showScore();//3、显示最终结果
this->saveRecord();//4、将分数保存到文件中
//重置比赛,获取记录
this->init_Speech();//初始化成员属性
this->create_Speaker();//创建12名选手
this->loadRecord();//加载记录
cout << "本次比赛已结束!" << endl;
system("pause");
system("cls");
}
//抽签
void SpeechManager::speechDraw()
{
cout << "参加第 " << this->m_Index << " 轮比赛的选手正在抽签..." << endl;
cout << "抽签结束,演讲顺序如下:" << endl;
if (this->m_Index == 1)//第1轮比赛
{
random_shuffle(this->v1.begin(), this->v1.end());
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
{
cout << *it << " ";
if (it == v1.begin() + 5)//分行输出两个小组的抽签结果
{
cout << endl;
}
}
cout << endl;
}
else//第2轮比赛
{
random_shuffle(this->v2.begin(), this->v2.end());
for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
cout << endl;
system("pause");
}
//比赛
void SpeechManager::speechContest()
{
cout << "-----第 " << this->m_Index << " 轮比赛开始!-----" << endl;
//准备临时容器,存放小组成绩
multimap<double, int, greater<double>>groupScore;
int num = 0;//记录人员个数,6人一组
vector<int>v_Srv;//比赛选手容器
if (this->m_Index == 1)
{
v_Srv = v1;
}
else
{
v_Srv = v2;
}
//遍历所有选手,开始比赛
for (vector<int>::iterator it = v_Srv.begin(); it != v_Srv.end(); it++)
{
num++;
//评委打分
deque<double>d;
for (int i = 0; i < 10; i++)
{
double score = (rand() % 401 + 600) / 10.f;//60~100
d.push_back(score);
}
sort(d.begin(), d.end(), greater<double>());//分数降序排列
d.pop_front();//去除最高分
d.pop_back();//去除最低分
double sum = accumulate(d.begin(), d.end(), 0.0f);//总得分
double avg = sum / (double)d.size();//平均分
//将平均分放入到map容器中
this->m_Speaker[*it].m_Score[this->m_Index - 1] = avg;
//将打分的数据存放到临时的小组容器中
groupScore.insert(make_pair(avg, *it));//key是选手的得分,value是选手的编号
//每6人取出前3名
if (num % 6 == 0)
{
cout << "第 " << num / 6 << " 小组的比赛结果如下:" << endl;
for (multimap<double, int, greater<double>>::iterator it = groupScore.begin(); it != groupScore.end(); it++)
{
cout << "编号:" << it->second << "\t姓名:"
<< this->m_Speaker[it->second].m_Name
<< "\t成绩:" << this->m_Speaker[it->second].m_Score[this->m_Index - 1] << endl;
}
//取走前3名
int count = 0;
for (multimap<double, int, greater<double>>::iterator it = groupScore.begin(); it != groupScore.end() && count < 3; it++, count++)
{
if (this->m_Index == 1)
{
v2.push_back((*it).second);
}
else
{
vVictory.push_back((*it).second);
}
}
cout << endl;
groupScore.clear();//一组结束之后,该容器要清空,不然又追加元素了
}
}
cout << "-----第 " << this->m_Index << " 轮比赛结束!-----" << endl;
system("pause");
}
//显示得分
void SpeechManager::showScore()
{
cout << "-----第 " << this->m_Index << " 轮比赛晋级选手信息如下:-----" << endl;
vector<int>v;
if (this->m_Index == 1)
{
v = v2;
}
else
{
v = vVictory;
}
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << "编号:" << *it << "\t姓名:"
<< this->m_Speaker[*it].m_Name
<< "\t成绩:" << this->m_Speaker[*it].m_Score[this->m_Index - 1] << endl;
}
cout << endl;
system("pause");
system("cls");
this->show_Menu();
}
//将最后前3名的得分保存到文件中
void SpeechManager::saveRecord()
{
ofstream ofs;
ofs.open("speech.csv", ios::out | ios::app);//用输出(追加)的方式打开文件---读文件
//将每个人的数据写入到文件中
for (vector<int>::iterator it = vVictory.begin(); it != vVictory.end(); it++)
{
ofs << *it << ","
<< this->m_Speaker[*it].m_Score[1] << ",";
}
ofs << endl;
ofs.close();//关闭文件
cout << "记录已保存!" << endl;
this->fileIsEmpty = false;//更改文件的状态
}
//读取记录
void SpeechManager::loadRecord()
{
ifstream ifs("speech.csv", ios::in);//读文件
if (!ifs.is_open())//文件不存在
{
this->fileIsEmpty = true;
ifs.close();
return;
}
//文件被清空的情况
char ch;
ifs >> ch;
if (ifs.eof())
{
this->fileIsEmpty = true;
ifs.close();
return;
}
//文件不为空
this->fileIsEmpty = false;
ifs.putback(ch);//将上面读取的单个字符读回来
int index = 0;//存放届数的变量
string data;
while (ifs >> data)
{
vector<string>v;//存放6个字符串的容器
int pos = -1;//保存","的位置的变量,-1表示未找到
int start = 0;//从起始位置开始查找
while (true)
{
pos = data.find(",", start);
if (pos == -1)//未找到的情况
{
break;
}
string temp = data.substr(start, pos - start);
v.push_back(temp);
start = pos + 1;
}
this->m_Record.insert(make_pair(index, v));
index++;
}
ifs.close();
}
//显示往届记录
void SpeechManager::show_Record()
{
if (this->fileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
}
else
{
for (int i = 0; i < this->m_Record.size(); i++)
{
cout << "-----第 " << i + 1 << " 届比赛结果记录如下-----" << endl;
cout << "冠军编号:" << this->m_Record[i][0] << " 得分:" << this->m_Record[i][1] << endl;
cout << "亚军编号:" << this->m_Record[i][2] << " 得分:" << this->m_Record[i][3] << endl;
cout << "季军编号:" << this->m_Record[i][4] << " 得分:" << this->m_Record[i][5] << endl;
}
}
system("pause");
system("cls");
}
void SpeechManager::clear_Record()
{
cout << "您确定要清空吗?" << endl;
cout << "1-确定" << endl;
cout << "2-返回" << endl;
int select = 0;
cin >> select;
if (select == 1)//清空文件
{
ofstream ofs;
ofs.open("speech.csv", ios::trunc);
ofs.close();
this->init_Speech();//初始化成员属性
this->create_Speaker();//创建12名选手
this->loadRecord();//加载记录
cout << "清空成功!" << endl;
}
system("pause");
system("cls");
}
//析构函数
SpeechManager::~SpeechManager(){}
3.4 演讲比赛流程管理系统.cpp
#include<iostream>
using namespace std;
#include"speechManager.h"
#include<ctime>
int main()
{
srand((unsigned int)time(NULL));//添加随机数种子
SpeechManager sm;//创建对象
int choice = 0;//记录用户输入的变量
while (true)
{
sm.show_Menu();
cout << "请输入您的选择:" << endl;
cin >> choice;
switch (choice)
{
case 1:
sm.start_Speech();//开始演讲比赛
break;
case 2:
sm.show_Record();//查看往届记录
break;
case 3:
sm.clear_Record();//清空比赛记录
break;
case 0:
sm.exit_System();//退出比赛程序
break;
default:
cout << "对不起,您的输入选择项不在系统服务内!" << endl;
cout << "您可以按任意键后选择重新输入!" << endl;
system("pause");//按任意键继续
system("cls");//清屏
break;
}
}
system("pause");
return 0;
}