c++ 演讲比赛系统

234 阅读3分钟

总览

黑马程序员
比赛规则: 共有 12 个人参加比赛,10名评委对其打分,去掉一个最高分,去掉一个最低分,求平均分
共比赛轮,
第一轮比赛分成组,取每组的前
第二轮个人取前名获奖

系统功能:

  1. 开始比赛
  2. 展示历史数据
  3. 清空比赛
  4. 退出系统

演讲者的类 包含演讲者的姓名,演讲者的两轮分数

class Speaker {
public:
	string m_Name; // 姓名
	double m_Score[2]; // 分数  最多有两轮得分 
};

前期工作:

开始比赛

// 存放的成员属性
	// 第一轮选手编号容器
	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;
// 构造函数
speechManager::speechManager() {
	this->initSpeech(); // 初始化
	this->createSpeaker(); // 创建参赛选手
	this->loadRecord(); // 装载记录
}

initSpeech()函数,初始化函数,把那些容器都置空

void speechManager::initSpeech() {
	// 容器都置空
	this->v1.clear();
	this->v2.clear();
	this->vVictory.clear();
	this->m_Speaker.clear();
	// 轮数为1
	this->m_Index = 1;
}

重头戏

// 开始比赛
void speechManager::startSpeech() {
	//第一轮比赛
	//1.抽签
	this->speechDraw();
	//2.比赛
	this->speechContest();
	//3.显示晋级结果
	this->showScore();

	// 第二轮比赛
	this->m_Index++;
	// 抽签
	this->speechDraw();
	// 比赛
	this->speechContest();
	// 显示最终结果
	this->showScore();
	// 保存分数 
	this->saveRecord();
	// 重置比赛
	this->initSpeech();
	this->createSpeaker();
	this->loadRecord();
	cout << "本届比赛结束" << endl;
	system("pause");
	system("cls");
}

抽签函数 speechDraw(),第一轮第二轮都需要抽签决定顺序,写一个就成,这里打乱顺序用的vector容器的 random_shuffle

void speechManager::speechDraw() {
	cout << "第 << " << this->m_Index << " >> 轮选手正在抽签" << endl;
	cout << "---------------------------" << endl;
	cout << "抽签后的演讲顺序如下:" << endl;
	if (this->m_Index == 1) {
		// 第一轮比赛
		random_shuffle(this->v1.begin(),this->v1.end());
		for_each(this->v1.begin(), this->v1.end(), printDraw);
		cout << endl;
	}
	else 
	{
		//第二轮比赛
		random_shuffle(this->v2.begin(), this->v2.end());
		for_each(this->v2.begin(), this->v2.end(), printDraw);
		cout << endl;
	}
	system("pause");
}

开始比赛speechContest()

使用临时容器multimap<double,int,greater> groupScore 存放小组成绩
double:成绩 int: 是编号
v_Src:判断第几轮 所放的容器不一样
num 用来记录人员个数
deque 用来存放十个专家给一名选手打的十个分数 去掉最高 去掉最低 求平均存入选手成绩(m_speaker)中,同时存入临时容器当中,以供打出选手成绩

void speechManager::speechContest() {
	cout << "------------第 <<" << this->m_Index << ">> 轮比赛正式打响-----------" << endl;

	// 临时容器,存放小组成绩
	multimap<double, int, greater<double>> groupScore;
	// 记录人员个数
	int num = 0;
	vector<int>v_Src;
	if (this->m_Index == 1) {
		v_Src = this->v1;
	}
	else
	{
		v_Src = this->v2;
	}
	// 遍历所有的参赛选手
	for (vector<int>::iterator it = v_Src.begin(); it != v_Src.end(); it++) {
		num++;
		// 评委打分
		deque<double> d;
		for (int i = 0; i < 10; i++) {
			double score = (rand() % 401 + 600) / 10.f; // 600-1000
			// cout << score << " ";
			d.push_back(score);
		}
		// cout << endl;
		// 排序
		sort(d.begin(),d.end(),greater<double>());
		d.pop_front(); // 去除最高分
		d.pop_back(); // 去除最低分

		double sum = accumulate(d.begin(),d.end(),0.0f); // 总分 
		double ave = sum / (double)d.size(); // 平均分

		// 打印平均分
		// cout << "编号:"<< *it <<" 姓名:" << this->m_Speaker[*it].m_Name << "  平均分:" << ave;

		// 将平均分放入到map容器里面
		this->m_Speaker[*it].m_Score[m_Index - 1] = ave;

		// 将打分的数据,存入临时容器
		groupScore.insert(make_pair(ave,*it)); // key是得分 value 是选手的编号

		// 每六个人取出前三名
		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 << " 姓名:" << 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; it++, count++)
			{
				if (this->m_Index == 1) 
				{
					v2.push_back(it->second);
				}
				else
				{
					vVictory.push_back(it->second);
				}
			}
			groupScore.clear();
			cout << endl;
		}
	}
	cout << "----------------第"<< this->m_Index << "轮比赛完毕---------------" << endl;
	system("pause");
}

显示晋级信息

    void speechManager::showScore() {
	cout << "第" << this->m_Index << "轮晋级结果为:" << endl;
	vector<int> v;
	if (this->m_Index == 1) {
		v = this->v2;
	}
	else {
		v = this->vVictory;
	}
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) 
	{
		cout << "编号: " << *it << " 姓名:" << this->m_Speaker[*it].m_Name << " 分数: " << this->m_Speaker[*it].m_Score[this->m_Index - 1] << endl;
	}
	cout << endl;

	system("pause");
	system("cls");	
}

存入文件当中

    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;
		cout << "文件不存在" << endl;
		ifs.close();
		return;
	}

	// 文件清空情况
	char ch;
	ifs >> ch;
	if (ifs.eof()) {
		cout << "文件为空" << endl;
		this->fileIsEmpty = true;
		ifs.close();
		return;
	}
	// 文件不为空的情况
	this->fileIsEmpty = false;

	ifs.putback(ch); // 将上面读取的单个字符放回去
	string data;
	int index = 0;
	while (ifs >> data)
	{
		vector<string>v;
		// 10010,86.4375,10006,83.675,10004,82.975,
		//cout << data << endl;
		int pos = -1; // 查找,的位置
		int start = 0;
		while(true)
		{
			pos = data.find(",", start);
			if (pos == -1)
			{
				break;
			}
			string temp = data.substr(start, pos - start);
			// cout << temp << endl;
			v.push_back(temp);
			start = pos + 1;
		}
		this->m_Record.insert(make_pair(index,v));
		index++;
	}
	ifs.close();
    }
void speechManager::showRecord() {
	if (this->fileIsEmpty) {
		cout << "文件为空或者不存在" << endl;
	}
	else 
	{
		for (int i = 0; i < this->m_Record.size(); i++)
		{
			cout << "第 " << i + 1 << " 届 "
				<< "冠军编号:" << this->m_Record[i][0] << "得分: " << this->m_Record[i][1] << "  "
				<< "亚军编号:" << this->m_Record[i][2] << "得分: " << this->m_Record[i][3] << "  "
				<< "季军编号:" << 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) {
		// 确认清空
		ofstream ofs("speech.csv",ios::trunc);
		ofs.close();
		this->initSpeech();
		this->createSpeaker();
		this->loadRecord();
		cout << "success" << endl;
	}
	system("pause");
	system("cls");
}