【黑马程序员C++】【基于STL的演讲比赛管理系统】

【黑马程序员C++】【基于STL的演讲比赛管理系统】

【黑马程序员C++】【基于STL的演讲比赛管理系统】

1、头文件

speaker.h

#pragma once
#include <iostream>
using namespace std;

//选手类
class Speaker
{
public:

    string m_Name;      //姓名
    double m_Score[2];  //分数 最多有两轮得分
};

speechManager.h

#pragma once
#include <iostream>
using namespace std;
#include <vector>
#include <map>
#include "speaker.h"
#include <algorithm>
#include <deque>
#include <functional>
#include <numeric>
#include <string>
#include <fstream>

//设计演讲管理类
class SpeechManager
{
public:

    //构造函数
    SpeechManager();

    //菜单功能
    void show_Menu();

    //4、退出系统
    void exitSystem();

    //析构函数
    ~SpeechManager();

    //初始化容器和属性
    void initSpeech();

    //创建12名选手
    void createSpeeker();

    //1、开始比赛   比赛整个流程控制函数
    void startSpeech();

    //抽签
    void speechDrew();

    //比赛
    void speechContest();
    
    //显示得分
	void showScore(); 
	
	//保存分数记录 
	void saveRecord();
	
	//读取记录
	void loadRecord();
	
	//2、显示往届选手记录
	void showRecord(); 
	
	//判断文件是否为空
	bool fileIsEmpty;
	
	//存放往届记录的容器 
	map<int,vector<string> >m_Record;
	
	//3、清空记录
	void clearRecord(); 

    //成员属性
    //保存第一轮比赛选手编号容器
    vector<int>v1;

    //第一轮晋级选手编号容器
    vector<int>v2;

    //胜出前三名选手编号容器
    vector<int>vVictory;

    //存放编号以及对应具体选手
    map<int,Speaker>m_Speaker;

    //存放比赛轮数
    int m_Index;
	
};

2、源文件

speechManager.cpp

#include "speechManager.h"

//构造函数
SpeechManager::SpeechManager()
{
    //初始化容器和属性
    this->initSpeech();

    //创建12名选手
    this->createSpeeker();
    
    //加载往届记录
	this->loadRecord(); 
}

//菜单功能
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::exitSystem()
{
    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::createSpeeker()
{
    string nameSeed = "ABCDEFGHIJKL";
    for(int i = 0;i < nameSeed.size(); i++)
    {
        string name = "选手";
        name += nameSeed[i];

        //创建具体选手
        Speaker sp;
        sp.m_Name = name;

        for(int j = 0; j < 2; j++)
        {
            sp.m_Score[j] = 0;
        }

        //创建选手编号  并且放入到 v1 容器中
        this->v1.push_back(i + 10001);

        //选手编号以及对应选手 放入到 map 容器中
        this->m_Speaker.insert(make_pair(i + 10001 , sp));
    }
}

//开始比赛   比赛整个流程控制函数
void SpeechManager::startSpeech()
{
    //第一轮开始比赛

    //1、抽签
    this->speechDrew();

    //2、比赛
    this->speechContest();

    //3、显示晋级结果
	this->showScore();
	
    //第二轮开始比赛
    this->m_Index++;

    //1、抽签
    this->speechDrew();

    //2、比赛
    this->speechContest();

    //3、显示最终结果
    this->showScore();

    //4、保存分数到文件中
    this->saveRecord();
    
    //重置比赛 
    //初始化容器和属性
    this->initSpeech();

    //创建12名选手
    this->createSpeeker();
    
    //加载往届记录
	this->loadRecord(); 
    
    cout << "本届比赛完毕!" << endl;
    
	system("pause");
	system("cls");  
}

//抽签
void SpeechManager::speechDrew()
{
    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");

    cout << endl;
}

//比赛
void SpeechManager::speechContest()
{
    cout << "----------第 << " << this->m_Index << " >> 轮比赛正式开始-----------" << endl;

    //准备临时容器 存放小组成绩
    multimap<double,int,greater<double> > groupScore;

    int num = 0;     //记录人员的个数  6 人一组

    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;
            // cout << score << " ";
            d.push_back(score);
        }
        // cout << endl;    //每十个人换行

        sort(d.begin(),d.end(),greater<double>());    //排序  降序
        d.pop_front();   //去除最高分
        d.pop_back();    //去除最低分

        double sum = accumulate(d.begin(),d.end(),0.0f);   //总分
        double avg = sum / (double)d.size();               //平均分

        // //打印平均分
        // cout << "编号: " << *it << " 姓名: " << this->m_Speraker[*it].m_Name 
        //      << " 获取平均分: " << avg << endl;

        //将平均分放入到map容器中       [*it] 是 map 的 key  m_Speraker[*it] 就是 Speaker
        //   m_Score的第一个位置的下标是  0  而   【47行代码初始化】 this->m_Index 此时为 1 所以要减 1 才是 0 

        this->m_Speaker[*it].m_Score[this->m_Index - 1] = avg;

        //将打分数据 放入到临时小组容器中
        groupScore.insert(make_pair(avg,*it));   //key 是得分 ,value 是具体选手编号
        //【每6人 取出前3名】 
        if(num % 6 == 0)              //当 num 为 6 时, num % 6 == 0 ,此时开始遍历前六个人 当 num 为 12 时,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();  //临时小组容器清空,【当 num 为 6 时, num % 6 == 0 ,此时开始遍历前六个人,遍历完第一组选手后,清空该 map 容器】 

        }
    }
    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 << " 姓名: " << this->m_Speaker[*it].m_Name << " 得分: " << this->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 << "," << this->m_Speaker[*it].m_Score[1] << ",";	  //  *it 选手编号    this->m_Speaker[*it].m_Score[1] 选手最终成绩 
	}
	ofs << endl;
	
	//关闭
	ofs.close();
	cout << "记录已经保存" << endl;
	
	//更改文件不为空的状态,否则  在按下 2 [查看往届比赛记录] 后 this->fileIsEmpty 还是 true 而不显示 
	this->fileIsEmpty = false; 
}

//读取记录
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;    //第几届      初始 设置 为 0 ,好访问 初始的 0 号位置 
	
	while(ifs >> data)    //  一行一行拿出数据   返回值为 ifs 本身
	{
		//cout << data << endl;	  //测试读出数据
		
		vector<string>v;    //存放 6个 string 字符串      【冠军  亚军  季军】 
		
		int pos = -1;   //查到 “,” 位置 的变量
		int start = 0;  //起始位置 
		
		while(true)
		{
			//eg: 10007,85.7875,10003,81.2625,10003,81.2625, 
			pos = data.find(",",start);
			if(pos == -1)
			{
				//没有找到情况
				break;
			}
			string temp = data.substr(start,pos - start);   // 用于截取字符串  substr(string, start, length);
			//cout << temp << endl;
			
			v.push_back(temp);        //存放一届的选手的记录 (临时数据) 
			
			start = pos + 1;        //更新  start 位置 
		}
		//存放 往届记录的容器  map<int,vector<string> >m_Record;
	
		this->m_Record.insert(make_pair(index,v));   // index 代表  key 值 ,要从零 开始 
		index++;
	}
	
	ifs.close();

//	//【it->first】	  代表第几届      【it->second】 代表  存放【冠军  亚军  季军】  的容器  v 
//	for(map<int,vector<string> >::iterator it = m_Record.begin();it != m_Record.end(); it++)
//	{
//		cout << it->first << "冠军编号:" << it->second[0] << " 分数:" << it->second[1] << endl;
//	}
}

//显示往届选手记录

void SpeechManager::showRecord()
{
	if(this->fileIsEmpty)
	{
		cout << "文件为空或者文件不存在!" << endl; 
	}
	else
	{
		for(int i = 0; i < this->m_Record.size(); i++)
		{
			cout << "第" << i+1 << "届"             //m_Record[i] 表示第 i 届   用  key 来 找  value  【i = 0 是 第一届 (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)
	{
		//确认清空
		ofstream ofs("speech.csv",ios::trunc);        //  trunc 【文件如果存在就清空,不存在就创建一个】
		ofs.close();
		
		//初始化容器和属性
	    this->initSpeech();
	
	    //创建12名选手
	    this->createSpeeker();
	    
	    //加载往届记录
		this->loadRecord(); 
		
		cout << "清空成功!" << endl; 
	}
	
	system("pause");
 	system("cls");
}

//析构函数
SpeechManager::~SpeechManager()
{

}

演讲比赛流程管理系统.cpp

#include <iostream>
using namespace std;
#include "speechManager.h"
#include <string>
#include <ctime>

int main()
{
    //随机数种子
    srand((unsigned int)time(NULL));

    //创建管理类对象
    SpeechManager sm;

    // //测试12名选手创建信息
    // for(map<int,Speaker>::iterator it = sm.m_Speraker.begin();it != sm.m_Speraker.end(); it++)
    // {
    //     cout << "选手编号: " << it->first << "姓名: " << it->second.m_Name << "分数: " 
    //          << it->second.m_Score[0] << endl;
    // }

    int choice = 0;     //用于存储用户输入

    while(true)
    {
        sm.show_Menu();

        cin >> choice;

        switch(choice)
        {
            case 1:    //开始比赛
                sm.startSpeech();
                break;
            case 2:    //查看往届比赛记录
            	sm.showRecord();
                break;
            case 3:    //清空比赛记录
            	sm.clearRecord();
                break;
            case 0:    //退出系统
                sm.exitSystem();
                break;
            default:
                system("cls");  //清屏
                break;
        }
    }

    system("pause");

    return 0;
}
### 黑马程序员 C++ 教学内容概述 黑马程序员C++ 学习教程主要分为基础阶段和提高阶段两大部分。以下是具体的内容划分: #### 基础阶段:面向对象编程的核心与精髓 该部分内容专注于 C++ 面向对象编程的基础理论和技术细节,帮助学生掌握 C++ 的核心概念[^1]。 - **内存分区模型** 讲解程序运行时内存如何分配以及不同区域的作用,例如栈区、堆区、全局/静态存储区和常量区等。这部分对于理解变量生命周期至关重要。 - **其他基础知识** 包括但不限于类与对象的概念、继承机制、多态特性及其实际应用案例分析等内容未被提及但属于此类教学范畴的一部分。 #### 提高阶段:高级功能与实战项目 此阶段深入探讨更复杂的主题并提供实践机会来巩固所学到的知识点[^2]。 - **模板类部分** 掌握泛型编程技巧,能够创建适用于多种数据类型的通用组件。 - **STL(Standard Template Library)** 熟悉标准库容器(vector, list, map 等)、迭代器及算法的应用场景。 - **C++ 函数对象及 STL 常用算法** 学会定义自己的可调用实体,并灵活运用 sort(), find_if() 这样的高效工具解决复杂问题。 #### 实战演练 - 综合能力提升 通过完成一系列精心设计的真实世界模拟任务进一步增强学员解决问题的能力: - **通讯录管理系统**: 设计实现一个可以增删改查联系人的小型软件系统. - **职工管理系统**: 构建支持员工信息录入查询统计等功能的企业内部管理平台原型. - **演讲比赛流程管理系统**: 开发一套用于组织管理和评分记录自动化处理的比赛辅助工具. - **机房预约系统**: 创建允许用户在线预订计算机实验室座位时间表安排方案. ```cpp // 示例代码展示逻辑运算符 '&&' 使用方法 #include <iostream> using namespace std; int main(){ int a=10,b=10; cout << (a && b) << endl; // 输出结果为 true 即数值表示形式下的 1 a = 10;b=0; cout << (a && b) << endl; // 此处由于b值为false故整体表达式的布尔值也为 false 数字上显示为0 a=b=0; cout << (a && b) << endl; // 同理当ab均为零则最终判定亦然呈现假状态即打印出的是整数意义上的0 system("pause"); return 0; } ``` 上述例子展示了基本逻辑操作符 `&&` 如何工作于两个整型变量之间比较其真伪情况[^3].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏花冬拾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值