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> multmapGroupdeque<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、第三轮比赛
这个程序还是有不完善的地方,希望后面可以将它改进的更好。