C++進階實例3--基於STL的演講比賽流程管理系統 1. 頭文件 1.1 speaker.h 1 #pragma once 2 #include<iostream> 3 4 using namespace std; 5 6 // 創建選手類 7 class Speaker { 8 public: ...
C++進階實例3--基於STL的演講比賽流程管理系統
1. 頭文件
1.1 speaker.h
1 #pragma once 2 #include<iostream> 3 4 using namespace std; 5 6 // 創建選手類 7 class Speaker { 8 public: 9 string m_Name; // 姓名 10 double m_Score[2]; // 分數,最多有兩輪得分 11 };
1.2 speechManager.h
#pragma once // 防止頭文件重覆包含 #include<iostream> #include<vector> #include<map> #include "speaker.h" using namespace std; // 演講比賽管理類 // 提供菜單界面與用戶交互 // 對演講比賽流程進行控制 // 與文件的讀寫交互 class SpeechManager { public: // 構造函數 SpeechManager(); // 析構函數 ~SpeechManager(); // 展示菜單 void show_Menu(); // 退出系統 void exitSysetm(); // 初始化屬性 void initSpeech(); // 初始化創建12名選手 void createSpeaker(); // 開始比賽 比賽流程式控制制 void startSpeech(); // 抽簽 void speechDraw(); // 比賽 void speechContest(); // 顯示比賽結果 void showScore(); // 保存記錄 void saveRecord(); // 讀取記錄 void loadRecord(); // 顯示往屆得分 void showRecord(); // 清空記錄 void clearRecord(); // 成員屬性 // 第一輪比賽選手 容器 12人 vector<int> v1; // 第一輪晉級選手 容器 6人 vector<int> v2; // 勝利前三名選手 容器 3人 vector<int> vVictory; // 存放編號 對應具體選手 容器 map<int, Speaker> m_Speaker; // 記錄比賽輪數 int m_Index; // 文件為空的標誌 bool fileIsEmpty; // 往屆記錄 map<int, vector<string>> m_Record; };
2.源文件
2.1 speechManager.cpp
#include<algorithm> #include<deque> #include<functional> #include<numeric> #include<fstream> #include "speechManager.h" // 構造函數 SpeechManager::SpeechManager() { // 初始化屬性 this->initSpeech(); // 創建選手 this->createSpeaker(); // 獲取往屆記錄 this->loadRecord(); } // 析構函數 SpeechManager::~SpeechManager() { } // 菜單功能 void SpeechManager::show_Menu() { cout << "**************************************" << endl; cout << "********* 歡迎參加演講比賽 *********" << endl; cout << "********* 1.開始演講比賽 *********" << endl; cout << "********* 2.查看往屆記錄 *********" << endl; cout << "********* 3.清空比賽記錄 *********" << endl; cout << "********* 0.開始演講比賽 *********" << endl; cout << "**************************************" << endl; cout << endl; } // 退出系統 void SpeechManager::exitSysetm() { cout << "歡迎下次使用!" << endl; system("pause"); exit(0); } // 初始化屬性 void SpeechManager::initSpeech() { // 保證容器為空 this->v1.clear(); this->v2.clear(); this->vVictory.clear(); this->m_Speaker.clear(); // 初始化比賽輪數 this->m_Index = 1; // 初始化記錄容器 this->m_Record.clear(); } // 初始化創建12名選手 void SpeechManager::createSpeaker() { string nameSeed = "ABCDRFGHIJKL"; for (int i = 0; i < nameSeed.size(); i++) { string name = "選手"; name += nameSeed[i]; // 創建具體選手 Speaker sp; sp.m_Name = name; for (int i = 0; i < 2; i++) { sp.m_Score[i] = 0; } // 12名選手編號 this->v1.push_back(i + 10001); // 選手編號 以及 對應選手 存放到map容器中 this->m_Speaker.insert(make_pair(i + 10001, sp)); } } // 抽簽 void SpeechManager::speechDraw() { cout << "第 << " << this->m_Index << " >> 輪比賽選手正在抽簽" << endl; cout << "------------------------------" << endl; cout << "抽簽後演講順序如下:" << endl; // 第一輪 if (this->m_Index == 1) { random_shuffle(v1.begin(), v1.end()); for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " "; } cout << endl; } else // 第二輪 { random_shuffle(v2.begin(), v2.end()); for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++) { cout << *it << " "; } cout << endl; } cout << "------------------------------" << endl; system("pause"); } // 比賽 void SpeechManager::speechContest() { cout << "------第" << this->m_Index << "輪正式比賽開始:-------" << endl; multimap<double, int, greater<double>> groupScore; // 臨時容器,保存key分數 value 選手編號 int num = 0; // 記錄人員數, 6個為1組 vector<int> v_Src; // 比賽的人員容器 if (this->m_Index == 1) { v_Src = v1; } else { v_Src = v2; } // 遍歷所有參賽選手 for (vector<int>::iterator it = v_Src.begin(); it != v_Src.end(); it++) { num++; // 評委打分 deque<double>d; for (int i = 0; i < 10; i++) { double score = (rand() % 401 + 600) / 10.f; // 600~1000 / 10 = 60~100 double // cout << score << " "; d.push_back(score); } sort(d.begin(), d.end(), greater<double>()); // 排序 d.pop_back(); // 去掉最低分 d.pop_front(); // 去掉最高分 double sum = accumulate(d.begin(), d.end(), 0.0f); // 獲取總分 double avg = sum / (double)d.size(); // 獲取平均分 this->m_Speaker[*it].m_Score[this->m_Index - 1] = avg; // 6個人一組,用臨時容器保存 groupScore.insert(make_pair(avg, *it)); if (num % 6 == 0) { cout << "第" << num / 6 << "小組比賽名次:" << endl; for (multimap<double, int, greater<double>>::iterator it = groupScore.begin(); it != groupScore.end(); it++) { cout << "編號:" << it->second << " 姓名:" << this->m_Speaker[it->second].m_Name << " 成績:" << this->m_Speaker[it->second].m_Score[this->m_Index - 1] << endl; } int count = 0; // 取前三名 for (multimap<double, int, greater<double>>::iterator it = groupScore.begin(); it != groupScore.end() && count < 3; it++, count++) { if (this->m_Index == 1) { v2.push_back((*it).second); } else { vVictory.push_back((*it).second); } } groupScore.clear(); cout << endl; } } cout << "------第" << this->m_Index << "輪比賽結束-------" << endl; system("pause"); } // 顯示比賽結果 void SpeechManager::showScore() { cout << "------第" << this->m_Index << "輪晉級選手信息如下:-------" << endl; vector<int>v; if (this->m_Index == 1) { v = v2; } else { v = vVictory; } for (vector<int>::iterator it = v.begin(); it != v.end(); it++) { cout << "選手編號:" << *it << " 姓名:" << m_Speaker[*it].m_Name << " 得分:" << m_Speaker[*it].m_Score[this->m_Index - 1] << endl; } cout << endl; system("pause"); system("cls"); this->show_Menu(); } // 保存記錄 void SpeechManager::saveRecord() { ofstream ofs; ofs.open("speech.csv", ios::out | ios::app); // 用輸出的方式打開文件 -- 寫文件 // 將每個人數據寫入的文件中 for (vector<int>::iterator it = vVictory.begin(); it != vVictory.end(); it++) { ofs << *it << "," << m_Speaker[*it].m_Score[1] << ","; } ofs << endl; ofs.close(); cout << "記錄已經保存" << endl; // 有記錄了,文件不為空 this->fileIsEmpty = false; } // 開始比賽 比賽流程式控制制 void SpeechManager::startSpeech() { // 第一輪比賽 // 1.抽簽 speechDraw(); // 2.比賽 speechContest(); // 3.顯示晉級結果 showScore(); // 第二輪比賽 this->m_Index++; // 1.抽簽 speechDraw(); // 2.比賽 speechContest(); // 3.顯示最終結果 showScore(); // 4.保存分數 saveRecord(); // 重置比賽 // 初始化屬性 this->initSpeech(); // 創建選手 this->createSpeaker(); // 獲取往屆記錄 this->loadRecord(); cout << "本屆比賽結束!" << endl; system("pause"); system("cls"); } // 讀取記錄 void SpeechManager::loadRecord() { ifstream ifs("speech.csv", ios::in); // 輸入流對象,讀取文件 if (!ifs.is_open()) { this->fileIsEmpty = true; //cout << "文件不存在!" << endl; ifs.close(); return; } char ch; ifs >> ch; if (ifs.eof()) { cout << "文件為空" << endl; this->fileIsEmpty = true; ifs.close(); return; } // 文件不為空 this->fileIsEmpty = false; ifs.putback(ch); // 讀取的單個字元放回去 string data; int index = 0; while (ifs >> data) { vector<string>v; int pos = -1; int start = 0; while (true) { pos = data.find(",", start); // 從0開始查找 if (pos == -1) { break; // 找不到break返回 } string tmp = data.substr(start, pos - start); // 找到了,進行分割,參數1:起始位置,參數2:截取長度 v.push_back(tmp); start = pos + 1; } this->m_Record.insert(make_pair(index, v)); index++; } ifs.close(); } // 顯示往屆得分 void SpeechManager::showRecord() { if (this->fileIsEmpty) { cout << "文件不存在,或記錄為空!" << endl; } else { for (int i = 0; i < this->m_Record.size(); i++) { cout << "第" << i + 1 << "屆 " << "冠軍編號:" << this->m_Record[i][0] << " 得分:" << this->m_Record[i][1] << " " "亞軍編號:" << this->m_Record[i][2] << " 得分:" << this->m_Record[i][3] << " " "季軍編號:" << this->m_Record[i][4] << " 得分:" << this->m_Record[i][5] << endl; } } system("pause"); system("cls"); } // 清空記錄 void SpeechManager::clearRecord() { cout << "確認清空?" << endl; cout << "1. 確認" << endl; cout << "2. 返回" << endl; int select = 0; cin >> select; if (select == 1) { // 打開模式 ios::trunc 如果存在 刪除文件並重新創建 ofstream ofs("speech.csv", ios::trunc); ofs.close(); // 初始化屬性 this->initSpeech(); // 創建選手 this->createSpeaker(); // 獲取往屆記錄 this->loadRecord(); cout << "清空成功!" << endl; } system("pause"); system("cls"); }
2.2 基於SLT的演講比賽流程管理系統
#include<iostream> #include<string> #include<vector> #include<algorithm> #include<functional> #include<ctime> #include "speechManager.h" using namespace std; // C++實例 // // 基於STL的演講比賽流程管理系統 // // 比賽規則: // 1.學校舉辦演講比賽,總共12人,比賽分兩輪:第一輪淘汰賽,第二輪決賽 // 2.選手編號為:10001~10012 // 3.比賽方式:分組比賽,每組6人 // 4.第一輪分為兩個小組,整體按照選手編號進行抽簽後順序演講 // 5.是個評委為每位選手打分,去掉一個最高分和一個最低分,求得平均分為本輪選手的成績 // 6.當小組演講結束後,淘汰組內排名最後的三個選手,前三名晉級,進入下一輪的比賽 // 7.第二輪為決賽,前三名勝出 // 8.每輪比賽過後需要顯示晉級選手的信息 // // 程式功能: // 1.開始演講比賽:完成整屆比賽的流程,每個比賽階段需要給用戶一個提示,用戶按任意鍵後進入下一個階段 // 2.查看往屆記錄:查看之前比賽前三名結果,每次比賽都會記錄到文件中,文件用.csv尾碼名保存 // 3.清空比賽記錄:將文件中的數據清空 // 4.退出比賽程式:可以退出當前程式 // // 1.創建管理類 // 提供菜單界面與用戶交互 // 對演講比賽流程進行控制 // 與文件的讀寫交互 // int main() { // 隨機數種子 srand((unsigned int)time(NULL)); // 1.創建管理類對象 SpeechManager sm; // 測試代碼 //for (map<int, Speaker>::iterator it = sm.m_Speaker.begin(); it != sm.m_Speaker.end(); it++) { // cout << "選手編號:" << it->first // << " 姓名:" << it->second.m_Name // << " 成績:" << it->second.m_Score[0] << endl; //} int choice = 0; // 用來存儲用戶的選擇 while (true) { // 展示菜單 sm.show_Menu(); cout << "請輸入您的選擇:" << endl; cin >> choice; // 接收用戶的選項 switch (choice) { case 1: // 開始比賽 sm.startSpeech(); break; case 2: // 查看記錄 sm.showRecord(); break; case 3: // 清空記錄 sm.clearRecord(); break; case 0: // 退出系統 sm.exitSysetm(); break; default: system("cls"); // 清屏 break; } } system("pause"); return 0; }