C++ 演讲比赛流程管理系统
演讲比赛流程管理系统
一、 程序需求
1、 比赛规则
- 学校举行一场演讲比赛,共有12人参加。比赛共两轮,第一轮为淘汰赛,第二轮为决赛
- 每名选手都有对应的编号,如 10001 ~ 10012
- 比赛方式:分组比赛,每组6人
- 第一轮分为两个小组,整体按照选手编号进行抽签后顺序演讲
- 十名评委分别给每名选手打分,去除最高分和最低分,求平均分为本轮选手的成绩
- 当选手演讲完后,淘汰组内排名最后的三个选手,前三名晋级,进入下一轮的比赛
- 第二轮为决赛,前三名胜出
- 每轮比赛过后需要显示晋级选手的信息
2、 程序功能
- 开始演讲比赛:完成整届比赛的流程,每个比赛阶段需要给用户一个提示。用户按任意键后继续下一个阶段
- 查看往届记录:查看之前比赛前三名结果,每次比赛都会记录到文件中,文件用.csv后缀名保存
- 清空比赛记录:将文件中数据清空
- 退出比赛程序:可以退出当前程序
二、 创建管理类
功能描述:
- 提供菜单界面与用户交互
- 对演讲比赛流程进行控制
- 与文件的读写交互
1、 创建文件
在头文件和源文件的文件夹下分别创建 speechManager.h 和 speechManager.cpp 文件
同时,创建 演讲比赛流程管理系统.cpp 作为主要运行函数
2、 头文件实现
在 speechManager.h 中
#pragma once #include <iostream> using namespace std; // 设计管理类 class SpeechManager { public: SpeechManager(); ~SpeechManager(); };
3、 源文件实现
在 speechManager.cpp 中
#include "speechManager.h" SpeechManager::SpeechManager() {} SpeechManager::~SpeechManager() {}
三、 菜单功能
功能描述:
- 与用户的沟通界面
1、 添加成员函数
在管理类 speechManager.h 中添加成员函数
// 菜单显示 void showMenu();
2、 实现函数
在 speechManager.cpp 中实现成员函数
void SpeechManager::showMenu() { // 显示菜单 cout << "**********************************" << endl; cout << "******** 欢迎参加演讲比赛 ********" << endl; cout << "******** 1、 开始演讲比赛 ********" << endl; cout << "******** 2、 查看往届记录 ********" << endl; cout << "******** 3、 清空比赛记录 ********" << endl; cout << "******** 0、 退出比赛程序 ********" << endl; cout << "**********************************" << endl; cout << endl; }
3、 测试函数
在主要运行函数中添加
#include "speechManager.h" #include <iostream> using namespace std; int main() { SpeechManager sm; sm.showMenu(); system("pause"); return 0; }
四、 退出功能
功能描述:
- 实现退出功能
1、 提供功能接口
在 main 函数中提供分支选择,提供每个功能接口
#include "speechManager.h" #include <iostream> using namespace std; int main() { // 实例化 SpeechManager sm; while (true) { sm.showMenu(); int choice; cout << "请输入你的选择:" << endl; cin >> choice; switch (choice) { case 0: // 退出程序 sm.exitSystem(); break; case 1: // 开始比赛 break; case 2: // 查看记录 break; case 3: // 清空记录 break; default: cout << "请按照要求输入哦!" << endl; system("pause"); system("cls"); break; } } system("pause"); return 0; }
2、 添加成员函数
在 speechManager.h 中添加成员函数
// 退出程序 void exitSystem();
3、 实现函数
在 speechManager.cpp 中实现函数
void SpeechManager::exitSystem() { cout << "欢迎下次使用!" << endl; system("pause"); exit(0); system("cls"); }
五、 演讲比赛功能
1、 功能分析
比赛流程分析:
抽签 -> 开始比赛 -> 显示第一轮比赛结果 -> 抽签 -> 开始演讲比赛 -> 显示前三名结果 -> 保存分数
2、 创建选手类
- 选手属性包含:选手姓名、分数
在 speechManager.h 中添加
class Speaker { public: string m_Name; // 姓名 double m_Score[2]; // 分数,存储两轮比赛的分数 };
注意:选手类要添加到 SpeechManager 类前面
3、 比赛
3.1 成员属性添加
- 在 speechManager.h 中 的 SpeechManager类 添加属性
// 成员属性 // 比赛选手 容器 12人 vector<int> v1; // 第二轮选手 容器 6人 vector<int> v2; // 胜利前三名 vector<int> vVictory; // 存放编号以及对应的 具体选手,容器 map<int, Speaker> m_Speaker; // 记录比赛轮数 int m_Index;
3.2 初始化属性
- 在 speechManager.h 中提供开始比赛的成员函数
// 初始化属性 void initSpeech();
3.3 函数实现
在 speechManager.cpp 中实现初始化属性
SpeechManager::SpeechManager() { // 初始化容器和属性 this->initSpeech(); } void SpeechManager::initSpeech() { // 容器都置空 this->v1.clear(); this->v2.clear(); this->vVictory.clear(); this->m_Speaker.clear(); // 初始化比赛轮数 this->m_Index = 1; }
3.4 创建选手
在 speechManager.h SpeechManager 类中提供开始比赛的成员函数
// 初始化创建12名选手 void createSpeaker();
在 speechManager.cpp 中实现函数
SpeechManager::SpeechManager() { // 初始化容器和属性 this->initSpeech(); // 创建12名选手 this->createSpeaker(); } void SpeechManager::createSpeaker() { string nameSeed = "ABCDEFGHIJKL"; for (int i = 0; i < nameSeed.size(); i++) { // 创建具体选手 Speaker sp; sp.m_Name = "选手"; sp.m_Name += nameSeed[i]; for (int j = 0; j < 2; j++) { // 初始化分数 sp.m_Score[j] = 0; } // 创建选手编号,并且放入 v1 容器中 this->v1.push_back(i + 10001); // 将选手编号一一对应每个选手 this->m_Speaker.insert(map<int, Speaker>::value_type(i + 10001, sp)); } }
3.5 开始比赛
- 在 speechManager.h 中提供开始比赛的成员函数
- 该函数功能是主要控制比赛的流程
// 开始比赛 void startSpeech();
- 在 speechManager.cpp 中将 startSpeech 的空实现先写入
- 我们可以可以先将整个比赛的流程写到函数中
void SpeechManager::startSpeech() { // 开始比赛,比赛整个流程控制函数 // 第一轮比赛开始 // 抽签 // 比赛 // 显示晋级结果 // 第二轮比赛开始 // 抽签 // 比赛 // 显示最终结果 // 保存分数 }
3.6 抽签功能
在 speechManager.h 中添加抽签函数声明
// 抽签 void speechDraw();
在 speechManager.cpp 中实现抽签函数
void SpeechManager::speechDraw() { string s(20, '-'); cout << "第" << this->m_Index << "轮比赛开始" << endl << s << endl << "抽签结果如下:" << endl; if (this->m_Index == 1) { // 第一轮比赛 random_shuffle(this->v1.begin(), this->v1.end()); for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " "; } cout << endl; } else { // 第二轮比赛 random_shuffle(this->v2.begin(), this->v2.end()); for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++) { cout << *it << " "; } cout << endl; } cout << s << endl; system("pause"); cout << endl; }
3.7 比赛过程
在 speechManager.h 中提供比赛的成员函数
// 比赛 void speechContest();
在 speechManager.cpp 中实现成员函数
void SpeechManager::speechContest() { string s(20, '-'); cout << "第" << this->m_Index << "轮比赛正式开始" << endl << s << endl; // 准备一个容器,存放小组数据,同时,降序排序 multimap<double, int, greater<double>> mp; 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++) { deque<double> d; // 存放分数 for (int i = 0; i < 10; i++) { double score = (rand() % 401 + 600) / 10.f; // 600 ~1000 10.f代表小数,分数为百分制 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); // 求和 double avg = sum / (double)d.size(); // 平均分 // 将平均分放入容器中 this->m_Speaker[*it].m_Score[this->m_Index - 1] = avg; // 将数据放入到临时小组中 mp.insert(make_pair(avg, *it)); // key 为得分 // 每六人,去后三名 if (mp.size() % 6 == 0) { cout << "第" << mp.size() / 6 << "组小组名次如下:" << endl; for (multimap<double, int, greater<double>>::iterator it = mp.begin(); it != mp.end(); it++) { cout << "编号:" << it->second << " 姓名:" << this->m_Speaker[it->second].m_Name << " 分数:" << this->m_Speaker[it->second].m_Score[0] << endl; } // 取走前三名,放入下一个容器 int count = 0; for (multimap<double, int, greater<double>>::iterator it = mp.begin(); it != mp.end() && count < 3; it++, count++) { if (this->m_Index == 1) { v2.push_back((*it).second); } else { vVictory.push_back((*it).second); } } mp.clear(); // 重置数据 } } cout << "第" << this->m_Index << "轮比赛结束!" << endl << s << endl; system("pause"); }
number = (rand()%(maxValue - minValue +1)) + minValue;
3.8 显示分数
在 speechManager.h 中提供显示分数的成员函数
// 显示分数 void showScore();
在 speechManager.cpp 中实现成员函数
void SpeechManager::showScore() { string s(20, '-'); cout << "第" << this->m_Index << "轮晋级选手信息如下:" << endl; cout << s << 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 << " 姓名:" << this->m_Speaker[*it].m_Name << " 得分:" << this->m_Speaker[*it].m_Score[this->m_Index - 1] << endl; } system("pause"); system("cls"); this->showMenu(); }
3.9 第二轮比赛
第二轮比赛流程同第一轮,只是比赛的轮数加一,其余流程不变
- 在startSpeech 比赛流程控制函数中,加入第二轮的流程
void SpeechManager::startSpeech() { // 开始比赛,比赛整个流程控制函数 // 第一轮比赛开始 // 抽签 this->speechDraw(); // 比赛 this->speechContest(); // 显示晋级结果 this->showScore(); // 第二轮比赛开始 this->m_Index++; // 抽签 this->speechDraw(); // 比赛 this->speechContest(); // 显示最终结果 this->showScore(); // 保存分数 }
3.10 保存分数
功能描述:
- 将每次演讲比赛的得分记录到文件中
功能实现:
- 在 speechManager.h 中添加保存记录的成员函数
// 保存记录 void saveRecord();
- 在 speechManager.cpp 中实现成员函数
void SpeechManager::saveRecord() { // 保存记录 ofstream ofs("./spech.csv", ios::out | ios::app); // 将每个选手的数据写入文件中 for (vector<int>::iterator it = vVictory.begin(); it != vVictory.end(); it++) { ofs << *it << "," << this->m_Speaker[*it].m_Score[1] << ","; } ofs << endl; // 关闭文件 ofs.close(); }
六、 查看记录
1、 读取记录分数
- 在 speechManager.h 中添加保存记录的成员函数
- 添加判断文件是否为空的标志
- 添加往届记录的容器
其中 m_Record 中的 key 代表第几届,value 记录具体的信息
// 读取记录 void loadRecord(); // 判断文件是否为空 bool fileEmpty; // 往届记录 map<int, vector<string>> m_Record;
在 speechManager.cpp 中实现成员函数
void SpeechManager::loadRecord() { ifstream ifs("./spech.csv", ios::in); // 读文件 // 文件不存在 if (!ifs.is_open()) { this->fileEmpty = true; ifs.close(); } // 文件清空情况 char ch; ifs >> ch; if (ifs.eof()) { this->fileEmpty = true; ifs.close(); } // 文件不为空 this->fileEmpty = 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); if (pos == -1) { break; } string temp = data.substr(start, pos - start); // 得到所有的字符串 v.push_back(temp); start = pos + 1; } this->m_Record.insert(make_pair(index + 1, v)); index++; } ifs.close(); }
2、 展示记录分数
- 在 speechManager.h 中添加展示保存记录的成员函数
// 显示数据 void showRecord();
- 在 speechManager.cpp 中实现函数
void SpeechManager::showRecord() { if (this->fileEmpty) { cout << "文件为空或者文件不存在" << endl; return; } for (map<int, vector<string>>::iterator it = m_Record.begin(); it != m_Record.end(); it++) { cout << "第" << it->first << "届比赛数据:" << endl << "冠军编号:" << it->second[0] << " 分数:" << it->second[1] << endl << "季军编号:" << it->second[2] << " 分数:" << it->second[3] << endl << "亚军编号:" << it->second[4] << " 分数:" << it->second[5] << endl; } system("pause"); system("cls"); }
七、 清空记录
1、 清空记录功能实现
- 在 speechManager.h 中添加保存记录的成员函数
// 清空记录 void clearRecord();
- 在 speechManager.cpp 中实现成员函数
void SpeechManager::clearRecord() { // 清空文件 cout << "是否确定清空文件?" << endl << "1、 是" << endl << "2、 否" << endl; int choice; cin >> choice; if (choice == 1) { // 确认清空 ofstream ofsm("./speech.csv", ios::trunc); ofsm.close(); cout << "清除成功!" << endl; // 重新初始化容器 // 初始化容器和属性 this->initSpeech(); // 创建12名选手 this->createSpeaker(); // 加载往届记录 this->loadRecord(); } else if (choice == 0) { cout << "正在退出!" << endl; return; } else { cout << "输入失败!" << endl; } }
2、 测试
在 main 函数中
#include "speechManager.h" #include <iostream> using namespace std; int main() { // 添加随机种子 srand((unsigned int)time(NULL)); // 实例化 SpeechManager sm; while (true) { sm.showMenu(); int choice; cout << "请输入你的选择:" << endl; cin >> choice; switch (choice) { case 0: // 退出程序 sm.exitSystem(); break; case 1: // 开始比赛 sm.startSpeech(); break; case 2: // 查看记录 sm.showRecord(); break; case 3: // 清空记录 sm.clearRecord(); system("pause"); system("cls"); break; default: cout << "请按照要求输入哦!" << endl; system("pause"); system("cls"); break; } } system("pause"); return 0; }
本文来自博客园,作者:Kenny_LZK,转载请注明原文链接:https://www.cnblogs.com/liuzhongkun/p/15919130.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?