基于STL的演讲比赛流程管理

news2024/11/24 17:37:31

比赛规则:

·学校举行一场演讲比赛,共有12个人参加。比赛共两轮,第一轮为淘汰赛,第二轮为决赛。·每名选手都有对应的编号,如10001~10012 ·比赛方式:分组比赛,每组6个人;
·第一轮分为两个小组,整体按照选手编号进行抽签后顺序演讲。

·十个评委分别给每名选手打分,去除最高分和最低分,求的平均分为本轮选手的成绩·当小组演讲完后,淘汰组内排名最后的三个选手,前三名晋级,进入下一轮的比赛。

·第二轮为决赛,前三名胜出·每轮比赛过后需要显示晋级选手的信息

程序功能:

·开始演讲比赛:完成整届比赛的流程,每个比赛阶段需要给用户一个提示,用户按任意键后继续下一个阶段

·查看往届记录:查看之前比赛前三名结果,每次比赛都会记录到文件中,文件用.csV后缀名保存

·清空比赛记录:将文件中数据清空

·退出比赛程序:可以退出当前程序 

一.头文件

1.speaker.h

#pragma once
#include <iostream>
using namespace std;

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

2.speechManager.h

#pragma once
#include <iostream>
using namespace std;
#include <vector>
#include <map>
#include "speaker.h"
#include <algorithm>
#include <numeric>

//设计演讲管理类
class SpeechManager
{
public:
	//构造函数
	SpeechManager();

	//菜单功能
	void show_Menu();
	
	//退出系统
	void exitSystem();

	//析构函数
	~SpeechManager();

	//初始化容器
	void initSpeech();

	//创建12名选手
	void createSpeaker();

	//开始比赛 比赛整个流程控制函数
	void startSpeech();

	//抽签
	void speechDraw();

	//成员属性
	//保存第一轮比赛选手的编号容器
	vector<int>v1;

	//第一轮晋级选手编号容器
	vector<int>v2;

	//胜出前三名选手编号容器
	vector<int>vVictory;

	//存放编号以及对应具体选手容器
	map<int, Speaker>m_Speaker;

	//比赛
	void speechContest();

	//记录比赛轮次
	int m_Index;

	//显示比赛结果
	void showScore();

	//保存记录
	void saveRecord();

	//读取记录
	void loadRecord();

	//显示往届记录
	void showRecord();

	//判断文件是否为空
	bool fileIsEmpty;
	map<int, vector<string>>m_Record;

	//清空文件
	void clearRecord();
};

二.源文件

1.speechManager.cpp

#include <iostream>
#include "speechManager.h"
using namespace std;
#include "speaker.h"
#include <string>
#include <deque>
#include <functional>
#include <fstream>

//构造函数
SpeechManager::SpeechManager()
{
	//初始化容器和属性
	this->initSpeech();

	//创建12名选手
	this->createSpeaker();

	//加载往届记录
	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::exitSystem()
{
	cout << "欢迎下次使用" << endl;
	system("pause");
	exit(0);
}

//初始化容器
void SpeechManager::initSpeech()
{
	//容器都置空
	this->v1.clear();
	this->v2.clear();
	this->vVictory.clear();
	this->m_Speaker.clear();

	//初始化比赛轮次
	this->m_Index = 1;

	//初始化记录器
	this->m_Record.clear();
}

//创建12名选手
void SpeechManager::createSpeaker()
{
	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;
		}
		//创建选手编号 并且放入到v1容器中
		this->v1.push_back(i + 10001);
		//选手编号以及对应选手 放入到map容器中
		this->m_Speaker.insert(make_pair(i + 10001, sp));
	}
}

//开始比赛 比赛整个流程控制函数
void SpeechManager::startSpeech()
{
	//第一轮开始比赛

	//1.抽签
	this->speechDraw();
	//2.比赛
	this->speechContest();
	//3.显示晋级结果
	this->showScore();
	//第二轮开始比赛
	this->m_Index++;
	//1.抽签
	this->speechDraw();
	//2.比赛
	speechContest();
	//3.显示最终结果
	this->showScore();
	//4.保存分数到文件中
	this->saveRecord();
	//重置比赛
	//初始化属性
	this->initSpeech();

	//创建选手
	this->createSpeaker();

	//获取往届记录
	this->loadRecord();

	cout << "本届比赛完毕" << endl;
	system("pause");
	system("cls");
}

//抽签
void SpeechManager::speechDraw()
{
	cout << "第 << " << this->m_Index << " >> 轮比赛选手正在抽签" << endl;
	cout << "----------------------------" << endl;
	cout << "抽签后演讲顺序如下: " << endl;
	if (this->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;//临时容器,保存key分数 value选手编号
	int num = 0;//记录人员个数 6个为1组

	vector<int>v_Src;//比赛的人员容器
	if (this->m_Index == 1)
	{
		v_Src = v1;
	}
	else
	{
		v_Src = 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 avg = sum / (double)d.size();//获取平均分

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

		//6个人一组 用临时容器保存
		groupScore.insert(make_pair(avg, *it));
		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 = v2;
	}
	else
	{
		v = 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");
	this->show_Menu();
}

//保存记录
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)
	{
		//cout << data << endl;
		vector<string>v;
		int pos = -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();
	//system("pause");
}

//显示往届记录
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();

		//创建12名选手
		this->createSpeaker();

		//加载往届记录
		this->loadRecord();

		cout << "清空成功!" << endl;
	}

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

//析构函数
SpeechManager::~SpeechManager()
{

}

2.演讲比赛流程管理系统.cpp

#include <iostream>
#include"speechManager.h"
using namespace std;
#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.startSpeech();
			break;
		case 2://查看记录
			sm.showRecord();
			break;
		case 3://清空记录
			sm.clearRecord();
			break;
		case 0://退出系统
			sm.exitSystem();
			break;
		default:
			system("cls");//清屏
			break;
		}
	}

	system("pause");
	return 0;
}

 三.程序效果图

 

 

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

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

相关文章

python: more Layer Architecture and its Implementation in Python and mysql 8.0

mysql 8.0 drop table DuStudentList;#学生表create table DuStudentList (StudentId INT NOT NULL AUTO_INCREMENT comment主键id, #自动增加,StudentName nvarchar(50) comment学生姓名,StudentNO varchar(50) comment学号, #学号StudentBirthday datet…

单片机学习12-串口通信

目录 串口通信实验 通信的基本概念 串行通信与并行通信 异步通信与同步通信 单工、半双工与全双工通信 通信速率&#xff08;比特率&#xff09; 单片机串口介绍 串口通信简介 串口相关寄存器 串口工作方式 方式 0 方式 1 方式 2 和方式 3 串口的使用方法 硬件设计…

基于matlab使用形态操作对视频流中的对象进行计数(附源码)

一、前言 此示例演示如何使用形态操作对视频流中的对象进行计数 输入视频流包含订书钉的图像。在此示例中&#xff0c;您使用平顶形态操作来消除不均匀的照明&#xff0c;并使用打开形态操作来消除订书钉之间的间隙。然后&#xff0c;将图像转换为二进制&#xff0c;对每个帧…

【Java】网络通信基础、协议分层及封装分用

IP地址&#xff1a;端口号概念格式 协议五元组协议分层TCP/IP五层模型 封装和分用 网络互连的目的是进行网络通信&#xff0c;也就是网络数据传输&#xff0c;更具体一点&#xff0c;是网络主机中的不同进程间基于网络来传输数据。 IP地址&#xff1a;端口号 概念 ip地址表示…

数据库监控与调优【十七】—— 表结构设计优化

表结构设计优化 第一范式&#xff08;1NF&#xff09; 字段具有原子性&#xff0c;即数据库的每一个字段都是不可分割的原子数据项&#xff0c;不能是集合、数组、记录等非原子数据项 当实体中的某个属性有多个值时&#xff0c;必须拆分为不同的属性 例子&#xff1a; 如图…

23.6.23

1.整理用户相关的指令、整理磁盘相关的指令 &#xff08;1&#xff09;用户相关 创建用户&#xff1a;sudo adduser 用户名 给新用户添加sudo权限&#xff1a;sudo vim /etc/sudoers 添加后wq&#xff01;强制退出 删除用户&#xff1a;sudo userdel &#xff08;-r&#x…

tomcat环境部署

目录 一、安装jdk 1、关闭防火墙&#xff0c;将安装 Tomcat 所需软件包传到/opt目录下&#xff0c;安装JDK 2、设置JDK环境变量 3、使用文本工具编写java源代码 二、安装启动Tomcat 1、解包 2、后台启动 3、使用80端口访问 一、安装jdk 在部署 Tomcat 之前必须安装好…

Java学习629

线程安全 开发中银行排号&#xff0c;火车售票系统中多线程程序发生的问题 引入代码&#xff1a; package Test0626;class SaleTicket implements Runnable{int ticket 100;Overridepublic void run() {while(true){if (ticket > 0){System.out.println(Thread.currentT…

ROS2 launch文件同时引入yaml文件参数和自定义变量参数

0 背景 在ROS中&#xff0c;launch工具可以帮助用户同时启动多个节点&#xff0c;以及引入多种设置如参数导入、节点名重映射等。在ROS1中&#xff0c;launch文件通过xml语言编写&#xff0c;后缀名为.launch&#xff1b;而ROS2在xml的基础上&#xff08;后缀名为.xml&#xf…

【Servlet学习四】实现一个内存版本的表白墙~

目录 一、前端代码 二、后端代码实现 &#x1f308;1、全局类定义AppVar &#x1f308;2、实体类定义Message &#x1f308;3、获取所有信息&#xff1a;getMessageServlet实现前后端的交互 &#x1f308;4、添加数据&#xff1a;addMessageServlet&#xff0c;实现前后端…

notepad++去除换行符和空格

在notepad中按Ctrlh 1.去除换行符 输入如图所示的查找内容为\r\n&#xff0c;【替换为】不填写&#xff0c;勾选底部的【正则表达式】&#xff0c;然后点击【全部替换】 2. 按照逗号换行 输入如图所示的查找内容为,&#xff0c;【替换为】\r\n&#xff0c;勾选底部的【正则…

C# WinForm 选择打开文件和保存文件

做 winform 项目的时候正好遇到了记录一下&#xff1a; 打开文件 我们使用 OpenFileDialog 控件来打开文件选择框&#xff1a; 通过 Title 属性可以设置选择框的标题而 Filter 属性可以设置选中的文件类型&#xff0c;这个属性由两个部分组成 SVG files (*.svg)|*.svg &am…

九、云尚办公系统-管理端-审批管理

云尚办公系统&#xff1a;管理端-审批管理 B站直达【为尚硅谷点赞】: https://www.bilibili.com/video/BV1Ya411S7aT 本博文以课程相关为主发布&#xff0c;并且融入了自己的一些看法以及对学习过程中遇见的问题给出相关的解决方法。一起学习一起进步&#xff01;&#xff01;…

Unity导出到AS中真机测试apk没有问题,aab提交到GooglePlay审核通过,但是从Google Play下载的应用闪退问题

从Google Play下载的应用报错如下&#xff1a; backtrace: #00 pc 0x0000000000050748 /data/app/~~x94h_Fmdoj4Vj1NVQcL7sQ/com.id.hhhuhi-LpC7BJqILn3X29R8TffhuA/split_config.arm64_v8a.apk!libpairipcore.so (ExecuteProgram196) 06-26 20:39:40.526 13936 13936 F l…

基于Java+Vue前后端分离宠物领养系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

ML@集成学习@摘要

文章目录 集成学习refs摘要Note准确性和多样性 集成学习方法分类BoostingAdaBoost伪代码Adaboost小结 补充补充1补充2 BaggingBagging伪代码 特点算法效率直接应用于多分类 自助采样和包外估计随机森林 Stackingsklearn中的Stacking&#x1f388;构造初级学习器构造次级学习器 …

Ubuntu18.04 系统设置修改物理内存-迅为RK3568开发板

打开虚拟机&#xff0c;如下图。单击红色框中的“虚拟机”。如下图所示&#xff1a; 然后点击“设置”弹出虚拟机的设置界面&#xff0c;如下图所示&#xff1a; 更多教程B站搜&#xff1a;迅为3568开发板

RHEL8.2安装QEMU及KVM虚拟化

一、环境 操作系统&#xff1a;CentOS8.2CPU&#xff1a;4C内存&#xff1a;16G磁盘&#xff1a;250G&#xff0c;其中180G分配给/data&#xff0c;用于存储数据及kvm存储池。 二、安装步骤 dnf module install virt dnf install virt-install virt-viewer virt-manager -y三…

【Redis二】Redis优化之持久化

Redis优化之持久化 1.Redis高可用2.Redis持久化2.1 RDB 持久化2.1.1 触发条件2.1.2 执行流程2.1.3 启动时加载 2.2 AOF 持久化2.2.1 开启AOF2.2.2 执行流程2.2.3 文件重写触发方式2.2.4 文件重写的流程2.2.5 启动时加载 2.3 RDB和AOF的优缺点2.4 RDB AOF持久化的区别 3.Redis性…

如何理解 Istio Ingress, 它与 API Gateway 有什么区别?东西流量?南北流量?

文章目录 背景k8s的内部服务如何被外部访问东西流量南北流量流量管理的比较 IngressAPI GatewayIstio参考 背景 这三者都和流量治理密切相关&#xff0c;那么流量治理在过去和现在有什么区别呢&#xff1f;都是如何做的呢&#xff1f; 在学习istio的时候对流量管理加深了理解。…