C++提高篇 001 STL案例之演讲比赛

STL案例之演讲比赛

/*
 *运行平台:Visual Studio 2015(Debug x86)
 *参考资料:《C++ Primer Plus(第6版)》,传智扫地增C++提高课程

*/


一、比赛介绍与需求分析

1、比赛介绍

某市举行一场演讲比赛( speech_contest ),共有24个人参加。比赛共三轮,前两轮为淘汰赛,第三轮为决赛。
在这里插入图片描述

  • 比赛方式:分组比赛,每组6个人;选手每次要随机分组,进行比赛;
    第一轮分为4个小组,每组6个人。比如100-105为一组,106-111为第二组,依次类推, 每人分别按照抽签(draw)顺序演讲。当小组演讲完后,淘汰组内排名最后的三个选手,然后继续下一个小组的比赛。
    第二轮分为2个小组,每组6人。比赛完毕,淘汰组内排名最后的三个选手,然后继续下一个小组的比赛。
    第三轮只剩下6个人,本轮为决赛,选出前三名。

  • 比赛评分:10个评委打分,去除最低、最高分,求平均分
    每个选手演讲完由10个评委分别打分。该选手的最终得分是去掉一个最高分和一个最低分,求得剩下的8个成绩的平均分。
    选手的名次按得分降序排列,若得分一样,按参赛号升序排名。

2、需求分析

  • 要求:用STL编程,求解这个问题
    1)请打印出所有选手的名字与参赛号,并以参赛号的升序排列。
    2)打印每一轮比赛后,小组比赛成绩和小组晋级名单
    3)打印决赛前三名,选手名称、成绩。
  • 产生选手 ( ABCDEFGHIJKLMNOPQRSTUVWXYZ ) 个人信息:姓名、得分、选手编号
  • 第1轮 选手抽签 选手比赛 查看比赛结果
  • 第2轮 选手抽签 选手比赛 查看比赛结果
  • 第3轮 选手抽签 选手比赛 查看比赛结果

二、实现思路分析

1、信息存储

需要把选手信息、选手得分信息、选手比赛抽签信息、选手的晋级信息保存在容器中,需要涉及到各个容器的选型。(相当于信息的数据库E-R图设计)

  • class Speaker;:选手可以设计一个类Speaker(姓名和得分)
  • map<int, Speaker> mSpeaker:所有选手编号和选手信息
  • vecter<int> v1:所有选手的编号信息
  • vecter<int> v2:第1轮晋级名单
  • vecter<int> v3 :第2轮晋级名单
  • vecter<int> v4:第3轮前三名名单
  • multimap<int, int, greater<int> > multmapGrou:每个小组的比赛得分信息,按照从小到大的顺序放在 multimap<成绩, 编号, greater> multmapGroup
  • deque<int> dscore;:每个选手的得分,方便去除最低最高分

2、函数

  • /* 产生选手,得到第一轮比赛名单 */
void GenSpeaker(map<int, Speaker> &mSpeaker, vector<int> &v);
  • /* 选手抽签函数 */
void speech_contest_draw(vector<int> &v);
  • /* 选手比赛函数 */
void speech_contest(int index, map<int, Speaker> &mSpeaker, vector<int> &v1, vector<int> &v2);
  • /* 打印比赛结果函数 */
void speech_contest_print(int index, map<int, Speaker> &mSpeaker, vector<int> &v);

三、案例框架搭建

#include <iostream>
using namespace std;

#include "string"
#include <vector>
#include <list>
#include "set"
#include <algorithm>
#include "functional"
#include "iterator"  //输出流迭代器的头文件
#include<numeric>
#include "map"
#include "deque"

/* 存储选手个人信息:姓名和得分 */
class Speaker
{
public:
	char name[32];
	int source[3];
};

/* 产生选手,得到第一轮比赛名单 */
void GenSpeaker(map<int, Speaker> &mSpeaker, vector<int> &v)
{
	
}

/* 选手抽签函数 */
void speech_contest_draw(vector<int> &v)
{

}

/* 选手比赛函数 */
void speech_contest(map<int, Speaker> &mSpeaker, vector<int> &v1, vector<int> &v2)
{

}

/* 打印比赛结果函数 */
void speech_contest_print(map<int, Speaker> &mSpeaker, vector<int> &v)
{

}

void main()
{
	map<int, Speaker> mSpeaker;	//选手编号和选手信息
	vector<int> v1;				//所有选手编号
	vector<int> v2;				//一轮晋级选手编号
	vector<int> v3;				//二轮晋级选手编号
	vector<int> v4;				//三轮最终选手编号

	//产生选手,得到第一轮比赛名单
	GenSpeaker(mSpeaker, v1);
	
	//第一轮比赛:抽签 比赛 打印比赛结果
	speech_contest_draw(v1);
	speech_contest(mSpeaker, v1, v2);
	speech_contest_print(mSpeaker, v2);

	//第二轮比赛:抽签 比赛 打印比赛结果
	speech_contest_draw(v1);
	speech_contest(mSpeaker, v1, v2);
	speech_contest_print(mSpeaker, v2);

	//第三轮比赛:抽签 比赛 打印比赛结果
	speech_contest_draw(v1);
	speech_contest(mSpeaker, v1, v2);
	speech_contest_print(mSpeaker, v2);

	system("pause");
}

四、业务函数实现

#include <iostream>
using namespace std;

#include "string"
#include <vector>
#include <list>
#include "set"
#include <algorithm>
#include "functional"
#include "iterator"  //输出流迭代器的头文件
#include<numeric>
#include "map"
#include "deque"

/* 存储选手个人信息:姓名和得分 */
class Speaker
{
public:
	string name;
	int score[3];
};

/* 产生选手,得到第一轮比赛名单 */
void GenSpeaker(map<int, Speaker> &mSpeaker, vector<int> &v)
{
	//安排每个选手的个人信息和编号
	string _name = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	Speaker tmp;

	for(int i=0; i<24; i++)
	{
		tmp.name = "选手";
		tmp.name = tmp.name + _name[i];
		mSpeaker.insert(pair<int, Speaker>(i+100, tmp));
	}

	//安排编号
	for(int i=0; i<24; i++)
	{
		v.push_back(i+100);
	}
}

/* 选手抽签函数 */
void speech_contest_draw(vector<int> &v)
{
	random_shuffle(v.begin(), v.end());	//打乱顺序
}

/* 选手比赛函数 */
void speech_contest(int index, map<int, Speaker> &mSpeaker, vector<int> &v1, vector<int> &v2)
{
	//小组的比赛得分 记录下来;求出前三名 后3名
	multimap<int, int, greater<int>> multmapGroup; //小组成绩
	int tmpCount = 0;

	//比赛流程
	for (vector<int>::iterator v_it = v1.begin(); v_it != v1.end(); v_it++)
	{
		tmpCount++;

		//打分
		deque<int> dscore;
		for(int i=0; i<10; i++)	//随机打分模拟10个评委
		{
			dscore.push_back(50 + rand()%50);
		}

		sort(dscore.begin(), dscore.end());	//排序
		dscore.pop_back();	//去最大值
		dscore.pop_front();	//去最小值

		//求平均分,先求和,后求均
		int sum_score = accumulate(dscore.begin(), dscore.end(), 0);
		int ave_score = sum_score/dscore.size();

		//存入容器内
		mSpeaker[*v_it].score[index] = ave_score;
		multmapGroup.insert(pair<int, int>(ave_score, *v_it));

		//处理小组成绩
		if(tmpCount%6 == 0)
		{
			cout << "-----------------小组比赛成绩-----------------" <<endl;
			cout << "序号" << "\t" << "姓名" << "\t" << "得分" << endl;

			//输出6个人员的信息
			for(multimap<int, int, greater<int>>::iterator mul_it = multmapGroup.begin(); mul_it != multmapGroup.end(); mul_it++)
			{
				cout << mul_it->second << "\t" << mSpeaker[mul_it->second].name << "\t" << mSpeaker[mul_it->second].score[index] << endl; 
			}

			//前三名晋级
			while(multmapGroup.size() > 3)
			{
				multimap<int, int, greater<int>>::iterator mul_it = multmapGroup.begin();
				v2.push_back(mul_it->second);
				multmapGroup.erase(mul_it);
			}
			multmapGroup.clear();//清空
		}	
	}
};

/* 打印比赛结果函数 */
void speech_contest_print(int index, map<int, Speaker> &mSpeaker, vector<int> &v)
{
	cout << "-----------------晋级名单-----------------" <<endl;
	cout << "序号" << "\t" << "姓名" << "\t" << "得分" << endl;

	//输出6个人员的信息
	for(vector<int>::iterator v_it = v.begin(); v_it != v.end(); v_it++)
	{
		cout << *v_it << "\t" << mSpeaker[*v_it].name << "\t" << mSpeaker[*v_it].score[index] << endl;
	}
}

void main()
{
	map<int, Speaker> mSpeaker;	//选手编号和选手信息
	vector<int> v1;				//所有选手编号
	vector<int> v2;				//一轮晋级选手编号
	vector<int> v3;				//二轮晋级选手编号
	vector<int> v4;				//三轮最终选手编号

	//产生选手,得到第一轮比赛名单
	GenSpeaker(mSpeaker, v1);

	//第一轮比赛:抽签 比赛 打印比赛结果
	cout << "\n\n\n任意键,开始第1轮比赛" << endl;
	cin.get();
	speech_contest_draw(v1);
	speech_contest(0,mSpeaker, v1, v2);
	speech_contest_print(0,mSpeaker, v2);

	//第二轮比赛:抽签 比赛 打印比赛结果
	cout << "\n\n\n任意键,开始第2轮比赛" << endl;
	cin.get();
	speech_contest_draw(v1);
	speech_contest(1,mSpeaker, v2, v3);
	speech_contest_print(1,mSpeaker, v3);

	//第三轮比赛:抽签 比赛 打印比赛结果
	cout << "\n\n\n任意键,开始第3轮比赛" << endl;
	cin.get();
	speech_contest_draw(v1);
	speech_contest(2,mSpeaker, v3, v4);
	cout << "\n\n\n最终决赛获胜人员" << endl;
	speech_contest_print(2,mSpeaker, v4);
	system("pause");
}

五、运行结果

1、第一轮比赛

在这里插入图片描述

2、第二轮比赛

在这里插入图片描述

3、第三轮比赛

在这里插入图片描述
这个程序还是有不完善的地方,希望后面可以将它改进的更好。

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值