本篇涉及到的知识点
1、make_pair()创建数据(设m是map<int,string>型变量)
- m.insert(make_pair(1,”名字"));
- m.insert(pair<int,string>(1,“名字”));
2、greater内建对象,从大到小排序
3、accumulate()计算容器内数据的和
- type accumulate(begin(),end(),0);//0表示从0开始累和
4、random_shuffle()洗牌
- 该函数是一个inline模板函数
- void random_shuffle(begin(),end());
5、vector与map结合使用(vector只存编号,map存放编号与选手信息)
6、algorithm头文件中sort()只适用于可随机存取的容器(vector、deque)
所谓的随机存取:(这里理解错了的话请指教一下,谢谢)
- vector、deque的at()方法
- 普通数组的arr[i]
7、auto关键字(c++11新特性,VS2013部分支持,自己百度学习)
8、额外知识点:指针与引用的区别
- 指针本身是占据内存空间的,引用只是别名,不占据空间
- 指针定义后不必初始化,引用声明时必须初始化
- 指针可以更改指向,引用只能指向初始的变量
====================================================
//STL评委打分案例
//24名选手参加比赛,10个评委打分
//共三轮,选出最终的3名选手()分数最高
/*
产生选手 姓名 得分 编号
第1轮 选手抽签 选手比赛 查看比赛结果
第2轮 选手抽签 选手比赛 查看比赛结果
第3轮 选手抽签 选手比赛 查看比赛结果
*/
代码中有注释,所以直接贴代码了
#define _CRT_SECURE_NO_WARNINGS //关闭VS编译器的安全检查(比如对scanf的检查)
#include<iostream>
#include<map>
#include<vector>
#include <deque>
#include <string>
#include<algorithm> //random_shuffle()
#include<numeric> //accumulate()
#include <functional> //greater
#include <ctime> //time()
using namespace std;
class Speaker{
public:
string m_Name;
int m_Score[3];//表示选手在三轮中的得分,默认全部初始为0
};
//参数需要使用用引用,否则创建的对象不在容器中
//v选手编号 m选手信息
void createSpeaker(vector<int>& v,map<int,Speaker>& m){
string nameSeed = "ABCDEFGHIJKLMNOPQRSTUVWX";
for (int i = 0; i < nameSeed.size(); ++i){
string name = "选手";
name += nameSeed[i];
Speaker sp; sp.m_Name = name;
for (int j = 0; j < 3; ++j)
sp.m_Score[j] = 0;
v.push_back(i + 100); //编号100-123
m.insert(make_pair(i + 100, sp));//编号、选手
}
}
//v 选手编号
void speechDraw(vector<int> v){
random_shuffle(v.begin(), v.end());//洗牌
}
//index表示第几轮比赛 v1为参赛编号 m为参赛选手信息 v2作为输出参数,表示晋级名单
void speechContest(int index,vector<int>& v1, map<int, Speaker>& m, vector<int>& v2){
srand((unsigned)time(NULL));//随机数种子
int score; //记录评委的打分
int num = 0;
//key 分数 value 编号 groupMap为存放小组信息的临时容器(6人为一个小组)
multimap<int, int, greater<int>> groupMap;//greater内建的函数对象 从大到小排序
for (vector<int>::iterator it = v1.begin(); it != v1.end(); ++it){
++num; //计数6个人
deque<int> d;
for (int i = 0; i < 10; ++i){//10个评委
score = rand() % 41 + 60;//60-100
d.push_back(score);
}
//排序
sort(d.begin(), d.end());
//去除最低最高
d.pop_back();
d.pop_front();
//累计分数
int sum = accumulate(d.begin(), d.end(),0);//从0开始累计
int avg = sum / d.size();
//将平均分存到m容器(avg是编号为*it的选手在本轮的得分)
m[*it].m_Score[index - 1] = avg;
//临时容器存入数据(分数,编号)
groupMap.insert(make_pair(avg, *it));
//每6个人 取前3名晋级
if (num % 6 == 0){
/*cout << "小组比赛成绩:" << endl;
for (multimap<int, int, greater<int>>::iterator mit = groupMap.begin(); mit != groupMap.end(); ++mit){
cout << "编号:" << mit->second << " 姓名:" << m[mit->second].m_Name << " 分数" << mit->first << endl;
}*/
int count = 0;
for (multimap<int, int, greater<int>>::iterator mit = groupMap.begin(); mit != groupMap.end() && count != 3; ++mit, ++count)
v2.push_back(mit->second);//晋级选手的编号
groupMap.clear();//清空临时容器,存放下一组信息
}
}
}
//index第几轮比赛 v2本轮晋级名单 m所有选手的信息
void showScore(int index, vector<int>& v2, map<int, Speaker>& m){
cout << "第 " << index << " 轮比赛成绩如下" << endl;
for (map<int, Speaker>::iterator it = m.begin(); it != m.end(); ++it){
cout << "编号:" << it->first << " 姓名:" << it->second.m_Name << " 得分:" << it->second.m_Score[index - 1] << endl;;
}
cout <<"第 "<<index<< " 轮晋级名单如下:" << endl;
for (auto i : v2) //auto关键字为C++11的特性,VS2013部分支持
cout << i << " ";
cout << endl;
}
int main(){
vector<int> v1;
map<int, Speaker> m;//选手编号和具体的选手
//创建选手
createSpeaker(v1,m);
//抽签
speechDraw(v1);
vector<int> v2;//晋级的选手编号
//第1轮比赛
speechContest(1,v1, m, v2);
//显示比赛结果 轮数 晋级编号 具体信息
showScore(1, v2, m);
//第2轮比赛
speechDraw(v2);
vector<int> v3;
speechContest(2, v2, m,v3);
showScore(2, v3, m);
//第2轮比赛
speechDraw(v3);
vector<int> v4;
speechContest(3, v3, m, v4);
showScore(3, v4, m);
//for (map<int, Speaker>::iterator it = m.begin(); it != m.end(); ++it){
// cout << it->first << " " << it->second.m_Name << endl;
//}
system("pause");
return 0;
}