19【综合案例:基于STL的演讲比赛流程管理系统】
SpeechContest.cpp
1 #include<iostream> 2 #include<cstdlib> 3 using namespace std; 4 #include "speechManager.h" 5 #include<map> 6 #include "speaker.h" 7 #include<string> 8 #include<ctime> 9 10 11 /* 12 比赛规则 13 学校举行一场演讲比赛,共有12个人参加。比赛共两轮,第一轮为淘汰赛,第二轮为决赛。 14 比赛方式:分组比赛,每组6个人;选手每次要随机分组,进行比赛 15 每名选手都有对应的编号,如 10001 ~ 10012 16 第一轮分为两个小组,每组6个人。 整体按照选手编号进行抽签后顺序演讲。 17 当小组演讲完后,淘汰组内排名最后的三个选手,前三名晋级,进入下一轮的比赛。 18 第二轮为决赛,前三名胜出 19 每轮比赛过后需要显示晋级选手的信息 20 程序功能 21 开始演讲比赛:完成整届比赛的流程,每个比赛阶段需要给用户一个提示,用户按任意键后继续下 22 一个阶段 23 查看往届记录:查看之前比赛前三名结果,每次比赛都会记录到文件中,文件用.csv后缀名保存 24 清空比赛记录:将文件中数据清空 25 退出比赛程序:可以退出当前程序 26 */ 27 28 29 int main() 30 { 31 srand((unsigned int)time(NULL)); 32 33 SpeechManager sm; 34 35 /* 36 //测试12名选手的创建 37 for(map<int, Speaker>::iterator it=sm.m_speaker.begin(); it!=sm.m_speaker.end(); it++) 38 { 39 cout << "编号:" << it->first << " 姓名:" << it->second.name << " 分数:" << it->second.score_arr[0] << endl; 40 } 41 */ 42 43 int choice = 0; 44 while(true) 45 { 46 sm.show_menu(); 47 48 cout << "请输入:" << endl; 49 cin >> choice; 50 51 switch(choice) 52 { 53 case 1: //开始比赛 54 sm.start_speech(); 55 break; 56 case 2: //查看往届比赛记录 57 //sm.load_record(); 58 sm.show_record(); 59 break; 60 case 3: //清空比赛记录 61 sm.clear_record(); 62 break; 63 case 0: //退出系统 64 sm.exit_system(); 65 break; 66 default: 67 system("cls"); //清屏 68 cout << "输入错误" << endl; 69 break; 70 } 71 } 72 73 system("pause"); 74 return 0; 75 }
speaker.h
1 #pragma once 2 #include<iostream> 3 using namespace std; 4 5 6 class Speaker 7 { 8 public: 9 string name; 10 double score_arr[2]; //最多有两轮得分 11 };
speechManager.h
1 #pragma once 2 #include<iostream> 3 #include<cstdlib> 4 using namespace std; 5 #include<vector> 6 #include<map> 7 #include "speaker.h" 8 #include<algorithm> 9 #include<deque> 10 #include<functional> 11 #include<numeric> 12 #include<string> 13 #include<fstream> 14 15 16 class SpeechManager 17 { 18 public: 19 SpeechManager(); //构造 20 21 void show_menu(); 22 23 void exit_system(); 24 25 void init_contest(); 26 27 void create_speaker(); 28 29 void start_speech(); //开始比赛:比赛流程控制函数 30 31 void speech_draw(); 32 33 void contest(); 34 35 void show_score(); 36 37 void save_record(); 38 39 void load_record(); 40 41 void show_record(); 42 43 void clear_record(); 44 45 ~SpeechManager(); //析构 46 47 public: 48 vector<int> v1; //全部比赛选手容器 12人 49 vector<int> v2; //第一轮晋级选手容器 6人 50 vector<int> v3; //比赛胜利前三名容器 3人 51 52 map<int, Speaker> m_speaker; //存放选手编号以及对应选手的容器 53 int index; //记录比赛轮数 54 55 bool file_empty; 56 map<int, vector<string> > m_record; //key表示第几届,value表示每届信息 57 };
speechManager.cpp
1 #include "speechManager.h" 2 3 4 SpeechManager::SpeechManager() //构造 5 { 6 this->init_contest(); 7 this->create_speaker(); 8 this->load_record(); 9 } 10 11 12 void SpeechManager::show_menu() 13 { 14 cout << "********************************************" << endl; 15 cout << "************* 欢迎参加演讲比赛 ************" << endl; 16 cout << "************* 1.开始演讲比赛 *************" << endl; 17 cout << "************* 2.查看往届记录 *************" << endl; 18 cout << "************* 3.清空比赛记录 *************" << endl; 19 cout << "************* 0.退出比赛程序 *************" << endl; 20 cout << "********************************************" << endl; 21 cout << endl; 22 } 23 24 25 void SpeechManager::exit_system() 26 { 27 cout << "欢迎下次使用" << endl; 28 system("pause"); 29 exit(0); 30 } 31 32 33 void SpeechManager::init_contest() 34 { 35 //容器置空 36 this->v1.clear(); 37 this->v2.clear(); 38 this->v3.clear(); 39 this->m_speaker.clear(); 40 41 //初始化比赛轮数 42 this->index = 1; 43 44 this->m_record.clear(); 45 } 46 47 48 void SpeechManager::create_speaker() 49 { 50 string name_seed = "ABCDEFGHIJKL"; 51 for(int i=0; i<name_seed.size(); i++) 52 { 53 Speaker sp; 54 55 string name = "选手"; 56 name += name_seed[i]; 57 sp.name = name; 58 59 for(int j=0; j<2; j++) //初始化分数 60 { 61 sp.score_arr[j] = 0; 62 } 63 64 this->v1.push_back(i + 10001); //创建选手编号并放入到容器v1中 65 this->m_speaker.insert(make_pair(i+10001, sp)); //选手编号及选手放入到map容器中 66 } 67 } 68 69 70 void SpeechManager::start_speech() //开始比赛:比赛流程控制函数 71 { 72 //1 第一轮比赛 73 //1.1 抽签 74 this->speech_draw(); 75 //1.2 比赛 76 this->contest(); 77 //1.3 显示晋级结果 78 this->show_score(); 79 //2 第二轮比赛 80 this->index++; 81 //2.1 抽签 82 this->speech_draw(); 83 //2.2 比赛 84 this->contest(); 85 //2.3 显示最终结果 86 this->show_score(); 87 //2.4 保存分数 88 this->save_record(); 89 90 //PS:重置比赛,同构造函数 91 this->init_contest(); 92 this->create_speaker(); 93 this->load_record(); 94 95 cout << "本届比赛完结撒花" << endl; 96 system("pause"); 97 system("cls"); 98 } 99 100 101 void SpeechManager::speech_draw() 102 { 103 cout << "=================================第" << this->index << "轮比赛选手正在抽签================================" << endl; 104 105 cout << "======================================================================================" << endl; 106 cout << "抽签结果如下:" << endl; 107 if(this->index == 1) //第一轮比赛 108 { 109 random_shuffle(v1.begin(), v1.end()); 110 for(vector<int>::iterator it=v1.begin(); it!=v1.end(); it++) 111 { 112 cout << *it << " "; 113 } 114 cout << endl; 115 } 116 else //第二轮比赛 117 { 118 random_shuffle(v2.begin(), v2.end()); 119 for(vector<int>::iterator it=v2.begin(); it!=v2.end(); it++) 120 { 121 cout << *it << " "; 122 } 123 cout << endl; 124 } 125 cout << "======================================================================================" << endl; 126 127 system("pause"); 128 cout << endl; 129 } 130 131 132 void SpeechManager::contest() 133 { 134 cout << "===================================第" << this->index << "轮比赛正式开始==================================" << endl; 135 136 multimap<double, int, greater<double> > group_score;//临时容器存放小组成绩,greater<double>指定排序规则是降序,特别注意greater<double> >要有空格 137 int num = 0; //记录人员个数,6人一组 138 139 vector<int> v_src; //正在比赛选手的容器 140 if(this->index == 1) 141 { 142 v_src = v1; 143 } 144 else 145 { 146 v_src = v2; 147 } 148 149 for(vector<int>::iterator it=v_src.begin(); it!=v_src.end(); it++) //遍历所有选手进行比赛 150 { 151 num++; 152 153 //10个评委打分 154 deque<double> d; 155 for(int i=0; i<10; i++) 156 { 157 double score = (rand() % 401 + 600) / 10.f; // (600~1000)/10 158 //cout << score << " "; 159 d.push_back(score); 160 } 161 //cout << endl; 162 163 sort(d.begin(), d.end(), greater<double>()); //降序排序 164 d.pop_front(); //除去最高分 165 d.pop_back(); //除去最低分 166 167 double sum = accumulate(d.begin(), d.end(), 0.0f); 168 double avg = sum / (double)d.size(); 169 170 //cout << "编号:" << *it << " 姓名:" << this->m_speaker[*it].name << " 分数:" << avg << endl; 171 this->m_speaker[*it].score_arr[this->index - 1] = avg; //将最终得分放入map容器中 172 173 group_score.insert(make_pair(avg, *it)); //将打分数据放入小组临时容器中,key是得分value是具体参赛选手的编号 174 if(num%6 == 0) //每6人取出前三名 175 { 176 cout << "第" << num/6 << "小组比赛名次:" << endl; 177 for(multimap<double, int, greater<double> >::iterator it=group_score.begin(); it!=group_score.end(); it++) 178 { 179 cout << "编号:" << it->second << " 姓名:" << this->m_speaker[it->second].name << " 成绩:" << this->m_speaker[it->second].score_arr[this->index-1] << endl; 180 } 181 182 //取走前三名放到下一轮比赛中 183 int countt = 0; 184 for(multimap<double, int, greater<double> >::iterator it=group_score.begin(); it!=group_score.end()&&countt<3; it++, countt++) 185 { 186 if(this->index == 1) 187 { 188 v2.push_back((*it).second); 189 } 190 else 191 { 192 v3.push_back((*it).second); 193 } 194 } 195 196 group_score.clear(); 197 cout << endl; 198 } 199 } 200 201 cout << "=====================================第" << this->index << "轮比赛结束===================================" << endl; 202 system("pause"); 203 } 204 205 206 void SpeechManager::show_score() 207 { 208 cout << "===================================第" << this->index << "轮晋级选手信息==================================" << endl; 209 210 vector<int> v; 211 if(this->index == 1) 212 { 213 v = v2; 214 } 215 else 216 { 217 v = v3; 218 } 219 220 for(vector<int>::iterator it=v.begin(); it!=v.end(); it++) 221 { 222 cout << "编号:" << *it << " 姓名:" << this->m_speaker[*it].name << " 得分:" << this->m_speaker[*it].score_arr[this->index-1] << endl; 223 } 224 cout << endl; 225 226 cout << "==========================================================================================================" << endl; 227 system("pause"); 228 system("cls"); 229 230 this->show_menu(); // 231 } 232 233 234 void SpeechManager::save_record() 235 { 236 ofstream ofs; 237 ofs.open("speech.csv", ios::out|ios::app); //追加方式写文件 238 239 for(vector<int>::iterator it=v3.begin(); it!=v3.end(); it++) 240 { 241 ofs << *it << "," << this->m_speaker[*it].score_arr[1] << ","; 242 } 243 ofs << endl; 244 245 ofs.close(); 246 cout << "记录保存成功" << endl; 247 this->file_empty = false; 248 } 249 250 251 void SpeechManager::load_record() 252 { 253 ifstream ifs("speech.csv", ios::in); 254 255 if(!ifs.is_open()) 256 { 257 this->file_empty = true; 258 //cout << "文件不存在" << endl; 259 ifs.close(); 260 return; 261 } 262 263 char ch; 264 ifs >> ch; 265 if(ifs.eof()) 266 { 267 this->file_empty = true; 268 //cout << "文件为空" << endl; 269 ifs.close(); 270 return; 271 } 272 273 this->file_empty = false; 274 ifs.putback(ch); //将上面读取的单个字符再放回来 275 string data; 276 int index = 0; 277 while(ifs >> data) 278 { 279 //cout << data << endl; 280 281 //逆向解析字符串 282 vector<string> v; //存放6个字符串 283 int pos = -1; //记录查到的“,”位置 284 int start = 0; 285 while(true) 286 { 287 pos = data.find(",", start); 288 if(pos == -1) 289 { 290 //没找到 291 break; 292 } 293 string temp = data.substr(start, pos-start); 294 //cout << temp << endl; 295 v.push_back(temp); 296 start = pos + 1; 297 } 298 299 this->m_record.insert(make_pair(index, v)); 300 index++; 301 } 302 303 ifs.close(); 304 305 /* 306 for(map<int, vector<string> >::iterator it=m_record.begin(); it!=m_record.end(); it++) 307 { 308 cout << "第" << it->first+1 << "届比赛" << endl; 309 cout << "冠军编号:" << it->second[0] << " 分数:" << it->second[1] << endl; 310 } 311 */ 312 } 313 314 315 void SpeechManager::show_record() 316 { 317 if(this->file_empty) 318 { 319 cout << "文件不存在或记录为空" << endl; 320 } 321 else 322 { 323 for(int i=0; i<this->m_record.size(); i++) 324 { 325 cout << "===================================第" << i+1 << "比赛信息==================================" << endl; 326 cout << "冠军编号:" << this->m_record[i][0] << " 成绩:" << this->m_record[i][1] << endl; 327 cout << "亚军编号:" << this->m_record[i][2] << " 成绩:" << this->m_record[i][3] << endl; 328 cout << "季军编号:" << this->m_record[i][4] << " 成绩:" << this->m_record[i][5] << endl; 329 cout << "================================================================================" << endl; 330 } 331 } 332 333 system("pause"); 334 system("cls"); 335 } 336 337 338 void SpeechManager::clear_record() 339 { 340 cout << "确认清空吗?(不可恢复!1-确认,2-返回)" << endl; 341 int select; 342 cin >> select; 343 344 if(select == 1) 345 { 346 ofstream ofs("speech.csv", ios::trunc); //trunc方式打开文件,若存在则删除并重新创建空文件 347 ofs.close(); 348 349 //初始化 350 this->init_contest(); 351 this->create_speaker(); 352 this->load_record(); 353 354 cout << "清空成功" <<endl; 355 } 356 357 system("pause"); 358 system("cls"); 359 } 360 361 362 SpeechManager::~SpeechManager() //析构 363 { 364 365 }