STL演讲比赛流程管理系统

很难,一边看视频,一边思考了好多天

speaker.h

#pragma once//防止头文件重复包含 
#include<iostream>
using namespace std;

//设计选手类 
class Speaker{
	public:
	string m_Name;//姓名 
	double m_Score[2];//double带了浮点,防止重复   2代表可能有人是两轮 
};

speechManager.h

#pragma once
#include<iostream>
#include<vector>
#include<map>
#include"speaker.h"
#include<algorithm>
#include<deque>
#include<functional>
#include<numeric>
#include<string>
#include<fstream>
using namespace std;
//设计演讲管理类
class SpeechManager{
	public:
		//构造函数  声明 
		SpeechManager();
		
		//菜单功能
		void show_Menu();
		
		//退出系统
		void exitSysem(); 
		//析构函数  声明 
		~SpeechManager();
		
		//初始化容器和属性
		void initSpeech(); 
		
		//创建12名选手
		void createSpeaker(); 
		
		//开始比赛  比赛整个流程控制函数
		void startSpeech(); 
		
		//抽签
		void speechDraw(); 
		
		//比赛
		void speechContest();
		
		//显示得分
		void showScore(); 
		
		//保存记录 
		void saveRecord();
		
		//读取记录
		void loadRecord();
		
		//显示往届记录
		void showRecord();
		
		//清空文件
		 void clearRecord();
		
		//判断文件是否为空
		bool fileIsEmpty;
		
		//存放往届记录的容器
		map<int,vector<string>>m_Record; 
		 
		
		//成员属性
		//保存第一轮比赛选手编号容器 
		vector<int>v1;
		
		//第一轮晋级选手编号容器
		vector<int>v2;
		//胜出前三名选手编号容器
		vector<int>vVictory;
		
		//存放编号以及对应具体选手容器
		map<int,Speaker>m_Speaker; //map的意思是每人都有固定编号  不会重复 
		
		//存放比赛轮数
		int m_Index; 
}; 

speechManager.cpp

#include"speechManager.h"


	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;
	}
	void SpeechManager::exitSysem(){
		cout<<"欢迎下次使用"<<endl;
		system("pause");
		exit(0);//退出系统 
	}
	void SpeechManager::initSpeech(){
		//保证.h中容器都置空
		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;//将两轮得分都赋为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.抽签
	speechDraw();
	//2.比赛
	speechContest();
	//3.显示最终结果 
	showScore();
	//4.保存分数到文件中 
	this->saveRecord();
	
	//比赛完后查不到本届比赛的记录,没有实时更新
	//解决方法:比赛完毕后,所有数据重置(就是把构造函数中的三行代码赋值过来!!)
	
	//调用一下,在构造函数中初始化容器和属性 
		this->initSpeech() ;//自动 
		
		//初始化调用,	创建12名选手
		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");//按任意键进行下一个环节 
	cout<<endl;
}
		//比赛
void SpeechManager::speechContest(){
	cout<<"----------第"<<this->m_Index<<"轮比赛正式开始-----------"<<endl;
	
	//准备一个临时的容器	存放小组成绩
	multimap<double,int,greater<double>>groupScore;//大到小 
	
	int num=0;//记录人员个数6人一组 
	 
	vector<int>v_Src;//比赛选手的容器
	if(this->m_Index==1){
		v_Src=v1;//v1的人比赛 
	} 
	else{
		v_Src=v2;
	}
	
	//遍历所有选手进行比赛
	for(vector<int>::iterator it=v_Src.begin();it!=v_Src.end();it++){
		//it从10001开始 
		num++;
		
		//评委打分
		deque<double>d;
		for(int i=0;i<10;i++){
			double score=(rand()%401+600)/10.f;//600~1000点几 
//			测试的输出 
//			cout<<score<<" ";//10个评委打分具体分 
			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);//从0开始     
	/*平均分*/double avg=sum/(double)d.size();//整数强转成double类型   因为浮点和整数相除是整数
		
		//打印平均分测试 
	//	cout<<"编号:"<<*it<<"姓名" <<this->m_Speaker[*it].m_Name<<"获取平均分数"<<avg<<endl;
//		将平均分放入map容器中
		this->m_Speaker[*it].m_Score[this->m_Index-1]=avg;//关键 
		
		//将打分的数据放入到临时小组容器中
		groupScore.insert(make_pair(avg,*it));//key是得分  ,value是具体选手编号
		
		//每6人取出前三名
	if(num%6==0)//够6个人了,进行 
	{
			
	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;//it->second是编号 
				
			}
			//取走前三名
	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//通过key找value 
		<<" 得分:"<< 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);//  |用追加的方式写文件   app为叠加	
	
	//将每个选手数据写入到文件中
	for(vector<int>::iterator it=vVictory.begin();it!=vVictory.end();it++){
		ofs<<*it<<","<<this->m_Speaker[*it].m_Score[1]<<",";//逗号分割	
		//冠军亚军季军写在一行	 
	} //begin开始为一号位 
	ofs<<endl;//换行 
	
	//关闭
	ofs.close();
	cout<<"记录已经保存"<<endl; 
	
	//若记录为空或不存在,比赛完后查询提示依然为空
	//有记录了,文件不为空
	this->fileIsEmpty=false; 
}

	//读取记录
void SpeechManager::loadRecord(){
	ifstream ifs("speech.csv",ios::in);//读取文件   ios::in读文件
	if(!ifs.is_open())//打开失败 
	{
		this->fileIsEmpty=true;
//		cout<<"文件不存在"<<endl;
		ifs.close();
		return ;
	} 
	
	//文件清空情况
	char ch;
	ifs>>ch;
	if(ifs.eof())//为真 读到文件尾 
//	用来判断文件是否为空,如果为1,那就是空的
	 {
//		cout<<"文件为空"<<endl;
		this->fileIsEmpty=true;
		ifs.close();
		return ;
	}
	
	//前两种情况排除后,只剩一种情况了,不为空的
	//文件不为空
	this->fileIsEmpty=false;
	ifs.putback(ch);//将上面读取的单个字符  放回来
	
	string data;//字符串读入 
	int index=0;//默认第0届 
	
	while(ifs>>data)//读到data里面 
	{
//		cout<<data<<endl;
		//结果:10002,86.675,10009,81.3,10007,78.55,
		
		vector<string>v;//为了存放6个string字符串
		 
		//截取
		int pos=-1;//查到","位置的变量
		int start=0;
		
		while(true){
		pos=data.find(",",start); //逗号也占位 
		if(pos==-1){
			//没有找到情况	
			break; 
		}
		string temp=data.substr(start,pos-start);//求出子串   截取的位置是pos-start   temp为临时值接收
		//start从XX开始获取  //10002成功截取
		 
//		cout<<temp<<endl;//测试代码
		//将每个值截取成功 
//		成功遍历输出 
//		10002
//		86.675
//		10009
//		81.3
//		10007
//		78.55
		v.push_back(temp);//放入设置好的容器
		 
		start=pos+1 ;
		}
		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;
//	}//it->first指的是第几届 
}
	//显示往届记录
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);// ios::trunc文件若是存在就删除,然后重新创建一个空文件
		ofs.close();
		
		//然后状态也要做一个清空    将构造函数中三行代码复制过来 
		
		
		//调用一下,在构造函数中初始化容器和属性 
		this->initSpeech() ;//自动 
		
		//初始化调用,	创建12名选手
		this->createSpeaker(); //需要构造函数自动先创建选手 
		
		//加载往届记录
		this->loadRecord(); 
		
		cout<<"清空成功"<<endl;
	}
	//不用else
	system("pause");
	system("cls"); 
}
	SpeechManager::~SpeechManager()
	{
		
	 } 

main.cpp

#include<iostream>
using namespace std;
#include"speechManager.h"
#include<string>
#include<ctime>
int main(){
	//创建随机数种子
	srand((unsigned int)time(NULL)); //这样每次得分冠亚军都不一样了 
	//创建管理类的对象
	SpeechManager sm;
//	sm.show_Menu();

	//测试12名选手创建    可注释了 
//	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[0]<<endl;
//		
//	} 

	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.exitSysem();
				break;
			default:
				system("cls");// 清屏 
				break; 
		}
		 
	}
	
//	system("puase");
	return 0; 
}

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值