视频学习来源
https://www.bilibili.com/video/BV1et411b73Z?p=276
演讲比赛流程管理系统.cpp
#include "iostream"
#include "SpeechManager.h"
using namespace std;
int main()
{
srand((unsigned int)time(NULL));
speechManager sp;
while (true)
{
sp.menu();
cout << "请输入你的选择: " << endl;
int choice;
cin >> choice;
switch (choice)
{
case 1://开始比赛
sp.startSpeech();
break;
case 2://查看往届记录
sp.showRecord();
break;
case 3://清空比赛记录
sp.clearRecord();
break;
case 4://退出比赛
sp.exitSystem();
break;
default:
break;
}
}
system("pause");
return 0;
}
SpeechManager.cpp
#include "SpeechManager.h"
//构造函数
speechManager::speechManager()
{
//初始化属性
this->InitSpeech();
//创建选手
createSpeaker();
//读取记录
loadRecord();
}
//菜单
void speechManager::menu()
{
cout << "****************************************************************************" << endl;
cout << "******************************欢迎参加演讲比赛******************************" << endl;
cout << "*******************************1.开始演讲比赛*******************************" << endl;
cout << "*******************************2.查看往届记录*******************************" << endl;
cout << "*******************************3.清空比赛记录*******************************" << endl;
cout << "*******************************4.退出比赛程序*******************************" << endl;
cout << "****************************************************************************" << endl;
}
//退出系统
void speechManager::exitSystem()
{
cout << "是否确认退出系统:1.确认 2.返回" << endl;
int select;
cin >> select;
if (select == 1)
{
system("pause");
exit(0);
}
else
{
return;
}
}
//初始化容器和属性
void speechManager::InitSpeech()
{
//初始化成员
this->v1.clear();
this->v2.clear();
this->victory.clear();
this->m_speaker.clear();
//初始化比赛轮数
this->m_index = 1;
//初始化记录容器
this->m_record.clear();
}
//创建选手
void speechManager::createSpeaker()
{
string nameNum = "ABCDEFGHIJKL";//12名选手的标号
Speaker sp;
for (int i = 0; i < 12; i++)
{
string name = "选手";
name += nameNum[i];
//初始化speaker里面的分数
for (int i = 0; i < 2; i++)
{
sp.score[i] = 0;
}
sp.name = name;
//初始化成员编号
v1.push_back(i + 10001);
//编号和成员放入map一一对应,map容器用insert
this->m_speaker.insert(make_pair(i+10001, sp));
}
}
//开始比赛
void speechManager::startSpeech()
{
//抽签,将v1容器内顺序打乱
speechDraw();
//比赛
speechContest();
//显示比赛结果
showScore();
//--------------------------------------------------------------------------------------
//第二轮比赛
this->m_index++;
//抽签,将v2容器内顺序打乱
speechDraw();
//比赛
speechContest();
//显示比赛结果
showScore();
//保存记录
saveRecord();
//---------------------------------------------------------------------------------------
//重置比赛
//初始化属性
this->InitSpeech();
//创建选手
createSpeaker();
//读取记录
loadRecord();
cout << "本届比赛完毕" << endl;
system("pause");
system("cls");
}
//抽签
void speechManager::speechDraw()
{
cout << "第 <<" << this->m_index << ">> 轮比赛选手正在抽签: " << endl;
cout << "****************************************************************************" << endl;
cout << "抽签顺序如下:" << endl;
if (m_index == 1)
{
random_shuffle(v1.begin(), v1.end());
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;
}
cout << "****************************************************************************" << endl;
system("pause");
}
//比赛(最复杂)
void speechManager::speechContest()
{
cout << "第" << this->m_index << "轮比赛开始" << endl;
multimap<double,int,greater<double>> groupScore;//注意:这里的greater<double>没有括号
//("分数","编号"),临时容器存放数据,自动从大噶到校排序
int num=0;//记录人员个数,6人为一组
vector<int> v_Src;//比赛人员容器
if (this->m_index == 1) v_Src = v1;
else v_Src = v2;
deque<double> vScore;//利用队列,双端数组,方便删除首尾元素
//遍历成员评分
for (vector<int>::iterator it = v_Src.begin(); it != v_Src.end(); it++)
{
//cout << "选手编号 " << *it << endl;
num++;//人员个数加一
//评委打分
for (int i = 0; i < 10; i++)
{
double score = (rand() % 401 + 600) / 10.f;//(600~1000)/10
vScore.push_back(score);
}
//排序,对平均分数vScore排序
sort(vScore.begin(), vScore.end(), greater<double>());//内置函数,记得加functional
//去掉最高分,去掉最低分
vScore.pop_back();
vScore.pop_front();
double sum=0;
sum = accumulate(vScore.begin(), vScore.end(), 0.0f);//总分
double avg = sum / (double)vScore.size();//平均分
//每个人的平均分
//cout << *it << " " << this->m_speaker[*it].name << " " << avg << endl;
this->m_speaker[*it].score[this->m_index - 1] = avg;//入成员变量map中,将分数记录到对应编号下
//6人一组
groupScore.insert(make_pair(avg, *it));//临时容器存放数据,从大到小排好序
if (num % 6 == 0)
{
cout << "第 " << num / 6 << "组比赛名次 " << endl;
int count = 0;//用来记录遍历的6人中的前三名
for (multimap<double, int>::iterator it = groupScore.begin(); it != groupScore.end(); it++)
{
count++;
cout << "编号 " << (*it).second << "姓名 " << m_speaker[(*it).second].name << "成绩" << (*it).first << endl;
//记录晋级
if (m_index == 1 && count<=3)
{
//第一场比赛,将每组前三名放入v2
v2.push_back((*it).second);
}
else if (m_index == 2 && count <= 3)
{
//第二场比赛,将总数前三名放入victory
victory.push_back((*it).second);
}
}
//6人结果已经公布,清空临时容器multimap groupScore
groupScore.clear();
cout << endl;
}
}
cout << "第" << this->m_index << "轮比赛完毕" << endl;
system("pause");
}
//显示晋级选手信息
void speechManager::showScore()
{
cout << "第 " << this->m_index << "轮选手晋级信息如下" << endl;
if (this->m_index == 1)
{
for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
{
cout << "编号 " << (*it) << "姓名 " << m_speaker[(*it)].name << "成绩" << m_speaker[(*it)].score[this->m_index-1] << endl;
}
}
else
{
for (vector<int>::iterator it = victory.begin(); it != victory.end(); it++)
{
cout << "编号 " << (*it) << "姓名 " << m_speaker[(*it)].name << "成绩" << m_speaker[(*it)].score[this->m_index - 1] << endl;
}
}
cout << endl;
system("pause");
system("cls");
this->menu();
}
//保存记录
void speechManager::saveRecord()
{
//写文件
ofstream ofs;
ofs.open("speech.csv", ios::out | ios::app);//追加的方式写文件
//记录最后获胜的三名选手 编号在victory中
for (vector<int>::iterator it = victory.begin(); it != victory.end(); it++)
{
ofs << *it << "," << this->m_speaker[*it].score[1] << ",";
}
ofs << endl;//文件中写换行
ofs.close();
this->fileEmpty = false;
cout << "文件保存完毕" << endl;
}
//读取记录
void speechManager::loadRecord()
{
//ifstream读取文件操作
ifstream ifs;
ifs.open("speech.csv", ios::in);//输入流对象,读取文件
//文件是否存在
if (!ifs.is_open())
{
//cout << "文件不存在" << endl;
this->fileEmpty = true;
ifs.close();
return;
}
//文件是否为空
char ch;
ifs >> ch;
if (ifs.eof())
{
//cout << "文件为空" << endl;
this->fileEmpty = true;
ifs.close();
return;
}
//文件不为空
this->fileEmpty = false;
ifs.putback(ch);//读取的单个字符放回去
//开始读数据
string data;
vector<string> v;//读取字符串
int index = 0;//选手编号
while (getline(ifs,data))//读取字符串,一次读取了一行的字符串,
{//可以写成 ifs>>data ,一次读一串字符串,读到换行
int pos = -1;//查看到的逗号位置
int start = 0;
vector<string> v;//存放6个字符串
//确定“,”所在位置
while (true)
{
pos = data.find(",", start);
if (pos == -1)
{
//没有找到
break;
}
string temp = data.substr(start, pos - start);
//cout << temp << endl;;
v.push_back(temp);//字符串记录到v里
start = pos + 1;
}
this->m_record.insert(make_pair(index, v));
index++;
}
ifs.close();
}
//显示往届得分
void speechManager::showRecord()
{
if (this->fileEmpty)
{
cout << "文件不存在或文件为空" << endl;
}
else
{
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 << "是否确认清空?1.确认2.返回" << endl;
int select;
cin >> select;
if (select == 1)
{
//打开模式 ios::trunc 如果文件存在则删除文件并重新创建
ofstream ofs("speech.csv", ios::out|ios::trunc);
ofs.close();
//初始化属性
this->InitSpeech();
//创建选手
createSpeaker();
//读取记录
loadRecord();
cout << "文件清空成功" << endl;
}
system("pause");
system("cls");
}
//析构函数
speechManager::~speechManager()
{
}
SpeechManager.h
#pragma once
#include "iostream"
#include "Speaker.h"
#include "vector"
#include "map"
#include "algorithm"
#include "ctime"
#include "deque"
#include "functional"
#include "numeric"
#include "fstream"
using namespace std;
//演讲管理类,里面包含演讲流程的函数
class speechManager
{
public:
//构造函数
speechManager();
//析构函数
~speechManager();
//菜单
void menu();
//退出系统
void exitSystem();
//成员及属性(必须要初始化)
//第一轮比赛选手编号
vector<int> v1;
//第二轮比赛选手(第一轮的胜出者编号)
vector<int> v2;
//胜出选手
vector<int> victory;
//编号对应选手
map<int, Speaker> m_speaker;//写道这里报了错,把speaker里面自己写的默认构造虚构函数删掉就可以
//比赛场次
int m_index;
//初始化容器和属性
void InitSpeech();
//创建选手
void createSpeaker();
//开始比赛
void startSpeech();
//抽签
void speechDraw();
//比赛(最复杂)
void speechContest();
//显示晋级选手信息
void showScore();
//保存记录
void saveRecord();
//读取记录
void loadRecord();
//判断文件是否为空
bool fileEmpty;
//往届记录 (编号,字符串信息)
map<int, vector<string>> m_record;
//显示往届得分
void showRecord();
//清空文件
void clearRecord();
};
Speaker.h
#pragma once
#include "iostream"
#include "string"
#include "vector"
using namespace std;
class Speaker
{
public:
//参赛者姓名
string name;
//参赛者两次比赛所得分数
double score[2];//防止分数太多重复用double
//构造函数
};