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 }

 

上一篇:pytest系列(六) - fixture 进阶玩法 (2)


下一篇:未来的JavaScript记录与元组