基于STL的演讲比赛管理系统

news2024/12/23 7:02:44

目录

一、比赛规则描述

二、比赛程序的功能

三、比赛的运行结果

四、程序的实现

1、程序实现的大致思路

2、程序的模块化

<1>选手信息的类

<2>管理比赛所有进度的接口头文件

<3>比赛进行的实现

<4>用户的交互界面<演讲比赛管理系统.cpp>

3、待解决的问题

跟着黑马视频初学c++基础,用这个实例练习,许多更深一点的问题不清楚,欢迎评论区评论,共同学习进步!。


一、比赛规则描述

二、比赛程序的功能

三、比赛的运行结果

 

有之前的比赛记录,会显示四条往届的比赛记录

 

四、程序的实现

1、程序实现的大致思路

采用分文件编写的方式:

1、每一个选手的信息建立一个头文件<speaker.h>中,定义一个类存放。

2、对于比赛的流程与进行,建立一个头文件<speachManger.h>,用于声明所有的成员属性以及比赛流程的控制

3、建立一个<speachManger.cpp>文件用于所有成员函数的定义

4、建立一个<比赛管理系统.cpp>文件用于用户的接口,控制比赛的运行进度。

                                            

如何编写比赛的程序:

1、通过一个比赛流程的成员函数控制比赛的进度(第一轮抽签,比赛、显示晋级名单、第二轮抽签、比赛、显示获奖名单),两轮比赛的流程一致、都进行了抽签,比赛、显示晋级名单。

2、定义抽签、比赛、显示晋级名单的成员函数,两轮比赛选手数量有所不同,通过声明的三个vector容器控制两轮比赛各自的进行。一个是v1容器,用于存放第一轮比赛选手名单,一个是v2容器,用于存放第一轮晋级的名单,也就是第二轮的比赛名单,另一个是vectory容器,用于存放最终获奖名单。

3、显示往届的记录,需要文件的交互。

对于本次获奖的名单需要通过写文件进行保存,在用户使用显示往届的记录时,需要进行读文件加载往届的数据。

4、在文件的交互中,读文件时(调用显示往届记录的接口时)需要判断是否存在该文件,如果存在文件,文件是否为空,通过一个成员属性用于显示文件是否为空。

如果文件中有往届的记录,以字符串类型的方式截取每一届的记录存放在为字符串类型的vector容器中,而每一届的记录的获奖记录通过map容器进行存放,通过map容器的对组,控制每一届信息的存放。

文件操作之写操作:

      程序中的数据都是在内存中,程序结束后,数据就无法保存。所以需要文件交互的操作进行数据的保存。

文件操作之读操作:

     注意:虽然文件的写操作可以进行文件的保存,但是当关闭程序,程序再次运行时,并没有将上次程序运行后的数据读取到这次程序中。程序中也有清空文件的需求。

2、程序的模块化

<1>选手信息的类

<2>管理比赛所有进度的接口<speachManger.h>头文件

#pragma once
#include<iostream>
#include<vector>
#include<map>
#include"speaker.h"
using namespace std;
//设计演讲比赛管理类
class SpeachManger
{
public:
	//构造函数声明
	SpeachManger();
	//展示菜单
	void showmenu();
	//退出程序
	void exitSystem();
	//初始化成员属性
	void initspeach();
	//第一轮比赛成员
	vector<int>v1;
	//第一轮晋级比赛成员
	vector<int>v2;
	//胜出的前三名成员
	vector<int>vectory;
	//参赛成员信息
	map<int, Speaker>m_speaker;
	//记录比赛的轮
	int index;
	//标记文件是否为空
	bool FileIsEmpty;
	//存放往届记录的数据
	map<int, vector<string>>m_record;
	//创建speaker成员
	void createspeaker();
	//开始比赛的流程控制函数
	void startspeech();
	//抽签
	void speechDraw();
	//开始比赛
	void speechcontest();
	//显示晋级信息
	void showScore();
	//保存记录
	void saveScore();
	//读取记录
	void loadrecord();
	//显示往届记录信息
	void showrecord();
	//清空记录
	void clearrecord();
	//析构函数声明
	~SpeachManger();
};

<3>比赛进行的实现<speachManger.cpp>

#include<iostream>
#include"speachManger.h"
#include<string>
#include<vector>
#include<map>
#include<deque>
#include<functional>
#include<numeric>
#include<algorithm>
#include<fstream>
using namespace std;
//构造函数
SpeachManger::SpeachManger()
{
	//调用初始化成员属性接口
	this->initspeach();
	//调用创建选手信息的接口
	this->createspeaker();
	//加载往届的记录
	this->loadrecord();
}
//展示菜单
void SpeachManger::showmenu()
{
	cout << "********************************" << endl;
	cout << "******  欢迎参加演讲比赛  ******" << endl;
	cout << "*******  1、开始演讲比赛  ******" << endl;
	cout << "*******  2、查看往届记录  ******" << endl;
	cout << "*******  3、清空比赛记录  ******" << endl;
	cout << "*******  0、退出比赛程序  ******" << endl;
	cout << "********************************" << endl;
	cout << endl;
}
//初始化容器和属性
void SpeachManger::initspeach()
{
	//容器置为空
	this->v1.clear();
	this->v2.clear();
	this->vectory.clear();
	this->m_speaker.clear();
	//初始化比赛的轮数
	this->index = 1;
	//清空往届记录的容器,但是文件记录保存数据
	this->m_record.clear();
}
//创建比赛成员
void SpeachManger:: createspeaker()
{
	string nameseed = "ABCDEFGHIJKL";
	for (int i = 0; i < nameseed.size(); i++)
	{
		string name = "选手";
		name += nameseed[i];
		Speaker sp;
		sp.name = name;
		for (int i = 0; i < 2; i++)
			sp.gore[i] = 0;
		//选手的编号
		this->v1.push_back(1000 + i);
		//将选手的编号和信息存入到map容器中
		this->m_speaker.insert(make_pair(1000+i,sp));
	}
}
void SpeachManger::startspeech()
{
	//第一轮比赛
	//1、抽签
	this->speechDraw();
	//2、比赛
	this->speechcontest();
	//3、显示 晋级结果
	this->showScore();
	//第二轮比赛
	this->index++;
	//1、抽签
	this->speechDraw();
	//2、比赛
	this->speechcontest();
	//3、显示最终结果
	this->showScore();
	//4、保存分数到文件中
	this->saveScore();

	//用于查找此次程序运行中进行的比赛记录
	//此次比赛结束,重置比赛,便于下次比赛
    this->initspeach();
	/*调用创建选手信息的接口*/
	this->createspeaker();
	//加载往届的记录(包括此次程序运行中的记录)
	this->loadrecord();

	cout << "本届比赛结束" << endl;
	system("pause");
	system("cls");
}
抽签
void SpeachManger::speechDraw()//抽签功能的实现
{
	cout << "第--" << this->index << "--轮选手抽签开始!" << endl;
	cout << "--------------------------------------" << endl;
	cout << "经过抽签,演讲顺序如下:   " << endl;

	if (this->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 SpeachManger::speechcontest()
{
	cout << "----第" << this->index << "轮比赛正式开始-----" << endl;
	vector<int>s;    //存放选手的编号
	multimap<double, int, greater<double>>groupscore;  //用临时的map容器存放每组的选手
	int num = 0;   //统计每一组的目前的人数,当满一组时便于选择前三名
	if (this->index == 1)
		s = v1;
	else
		s = v2;       //第二轮存放第一轮晋级的选手编号
	//为每个选手打分
	for (vector<int>::iterator it = s.begin(); it != s.end(); it++)
	{
		num++;
		deque<double>g;
		for (int i = 0; i < 10; i++)
		{
			double s_gore = (rand() % 401 + 600) / 10.f;  //产生600-1000之间的百分数
			g.push_back(s_gore);
		}
		//进行排序从大到小
		sort(g.begin(), g.end(), greater<double>());
		//去掉最高分,去掉最低分
		g.pop_front();
		g.pop_back();
		//求总分然后求平均分
		double sum = accumulate(g.begin(), g.end(), 0.0f);
		double avg = sum / (double)g.size();
	    //平均分放到map容器中
		this->m_speaker[*it].gore[this->index - 1] = avg;
		//将平均分与其对应的编号存入临时map容器
		groupscore.insert(make_pair(avg, *it));
		//每6人一组取出前三名
		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 << "name: " << this->m_speaker[it->second].name
					<< " 分数为: " << this->m_speaker[it->second].gore[this->index - 1]<<endl;
			}
			//取走前三名
			int count = 0;  //限制迭代器的次数
			for (multimap<double, int, greater<double>>::iterator it2 = groupscore.begin(); it2 != groupscore.end()&&count<3; it2++,count++)
			{
				if (this->index == 1)
					v2.push_back(it2->second);   //第一轮晋级选手编号
				else
					vectory.push_back(it2->second);    //第二轮晋级选手编号
			}
			groupscore.clear();   //将已经评选好的小组的临时数据清空
			cout << endl;
		}
	}
	cout << "----第 " << this->index << "轮比赛结束" << endl;
	system("pause");
}

//显示晋级信息
void SpeachManger::showScore()
{
	cout << "第" << this->index << "轮晋级选手的信息" << endl;
	vector<int>v;
	//判断第几轮的输出
	if (this->index == 1)
		v = v2;
	else
		v = vectory;
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
		cout <<"选手编号: "<<*it<<" "<<" 姓名:"<<m_speaker[*it].name<<" "
		<<"分数: "<<m_speaker[*it].gore[this->index-1]<<endl;
	system("pause");
	system("cls");
	this->showmenu();
}

//保存记录
void SpeachManger::saveScore()
{
	ofstream ofs;
	ofs.open("speech.csv", ios::out |ios::app);
	for (vector<int>::iterator it = vectory.begin(); it != vectory.end(); it++)
		ofs << *it << "," << m_speaker[*it].gore[1]<<",";
	ofs << endl;
	ofs.close();
	cout << "记录已经保存" << endl;
	//文件保存后更改文件的状态
	this->FileIsEmpty = false;
}

//读取记录
void SpeachManger::loadrecord()
{
	ifstream ifs("speech.csv", ios::in);
	//判断文件是否存在,通过is_open判断文件是否可以打开
	if (!ifs.is_open())
	{
		cout << "文件不存在" << endl;
		this->FileIsEmpty = true;
		ifs.close();
		return;
	}
	//判断文件是否为空
	char c;
	ifs >> c;
	if (ifs.eof())
	{
		cout << "文件为空" << endl;
		this->FileIsEmpty = true;
		ifs.close();
		return;
	}
	//文件存在且不为空
	this->FileIsEmpty = false;
	ifs.putback(c);        //将上面读取的单个字符,放回来
	string data;
	int tindex = 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);
		start = pos + 1;       
		v.push_back(temp);
	}
	this->m_record.insert(make_pair(tindex, v));    //将每一届的获奖选手信息存入map容器中
	tindex++;
	}
	ifs.close();
}

//显示往届记录的信息
void SpeachManger::showrecord()
{
	if (this->FileIsEmpty)
	{
		cout << "文件为空或不存在" << endl;
	}
	else 
	{
		for (int i = 0; i <this-> m_record.size(); i++)
		{
			cout << "第" << i + 1 << "届获奖记录" << endl;
			cout << "冠军编号:" <<  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 SpeachManger::clearrecord()
{
	cout << "确认清空?" << endl;
	cout << "1、确认" << endl;
	cout << "2、返回" << endl;
	int choice = 0;
	cout << "请输入你的选择:" << endl;
	cin >> choice;
	if (choice == 1)
	{
		ofstream ofs("speech.csv", ios::trunc);  //删除该文件,然后再次创建该文件
		this->initspeach();
		this->createspeaker();
		this->loadrecord();   //加载往届为空的数据
		cout << "所有记录已经清空" << endl;
	}
	system("pause");
	system("cls");
}
//退出程序
void SpeachManger::exitSystem()
{
	cout << "欢迎下次使用" << endl;
	system("pause");
	exit(0);
}
SpeachManger::~SpeachManger()
{

}

<4>用户的交互界面<演讲比赛管理系统.cpp>

#include<iostream>
#include<map>
#include"speachManger.h"
#include<ctime>
using namespace std;
int main()
{
	srand((unsigned int)time(NULL));   //产生随机数种子,用于控制每次抽签的随机性
	SpeachManger sm;
	int choice = 0;  //用于用户的选择
	while (true)
	{
		sm.showmenu();
		cout << "请输入选项:" << endl;
		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;
}

3、待解决的问题

跟着黑马视频初学c++基础,用这个实例练习,许多更深一点的问题不清楚,欢迎评论区评论,共同学习进步!。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/504985.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue项目引入pwa使网页应用可安装

最近在使用vue项目时看到一个这样的效果&#xff0c;如图&#xff1a; 现在其实有很多网站都支持把网页安装到电脑或手机&#xff08;IOS Safari支持较好&#xff09;&#xff0c;如下图安装后的效果&#xff1a; 这些都是网页应用。 接下来介绍一下如何让你的vue2项目变得可以…

动态规划刷题篇【Day01】

目录 一.问题描述 描述 二.示例 三.动态规划方法 &#xff08;一&#xff09;最优子结构 &#xff08;二&#xff09;递推关系建立 &#xff08;三&#xff09;自底向上计算 &#xff08;四&#xff09;代码实现 一.问题描述 描述 输入一个长度为n的整型数组array&#xff…

Echarts 箱线图的详细配置过程

文章目录 Echarts 简介 Echarts 简介 ECharts&#xff08;百度开源的数据可视化库&#xff09;提供了丰富的图表类型&#xff0c;其中包括箱线图。箱线图是一种用于展示数据分布情况的图表类型&#xff0c;它可以显示数据的中位数、四分位数、最大值、最小值和异常值等信息。下…

23种设计模式之工厂方法模式

前言&#xff1a;大家好&#xff0c;我是小威&#xff0c;24届毕业生&#xff0c;在一家满意的公司实习。本篇文章将23种设计模式中的工厂方法模式&#xff0c;此篇文章为一天学习一个设计模式系列文章&#xff0c;后面会分享其他模式知识。 如果文章有什么需要改进的地方还请大…

水提金银花多糖通过调节NLRP3-IL-17信号轴减轻过敏性鼻炎

文章标题&#xff1a;Water-extracted Lonicera japonica polysaccharide attenuates allergic rhinitis by regulating NLRP3-IL-17 signaling axis 发表期刊&#xff1a;Carbohydrate Polymers 影响因子&#xff1a;10.723 作者单位&#xff1a;遵义医科大学 百趣提供服务…

五、Spring Cloud Alibaba-Feign

引入 基于之前的学习&#xff0c;我们目前调用是通过restTemplate硬编码方式调用的。 restTemplate.getForObject("http://stock-service/stock/reduce", String.class);还是很不方便&#xff0c;考虑直接用service.方法进行调用&#xff0c;从而引出Feign&#xff…

vue+elementui+nodejs校园高校餐厅点餐及订餐菜品推荐评价系统6927k

传统的销售模式&#xff0c;在实体店的紧跟式的销售模式&#xff0c;会给消费者一种不自由&#xff0c;被监视的感觉。餐厅点餐及推荐系统&#xff0c;紧跟数据时代的步伐&#xff0c;使用nodejs开发语言&#xff0c;配备MySQL数据库。扎根于实际问题所开发出来的一套系统。这个…

总结845

学习目标&#xff1a; 月目标&#xff1a;5月&#xff08;张宇强化前10讲&#xff0c;背诵15篇短文&#xff0c;熟词僻义300词基础词&#xff09; 周目标&#xff1a;张宇强化前3讲并完成相应的习题并记录&#xff0c;英语背3篇文章并回诵 每日必复习&#xff08;5分钟&#…

Windows 10 安装 MySQL

确认是否已安装 MySQL &#xff08;1&#xff09;按【winr】快捷键打开运行&#xff1b; &#xff08;2&#xff09;输入 services.msc&#xff1b; &#xff08;3&#xff09;点击【确定】&#xff0c;在打开的服务列表中查找 mysql 服务&#xff0c;如果没有 mysql 服务&…

HTAP for MySQL 在腾讯云数据库的演进

摘要&#xff1a;MySQL在充分利用多核计算资源方面比较欠缺&#xff0c;无法同时满足在线业务和分析型业务的客户需求&#xff0c;而单独部署一套专用的分析型数据库意味着额外的成本和复杂的数据链路。本次主题将介绍腾讯云数据库为满足此类场景而在HTAP for MySQL产品方面进行…

【数据挖掘与商务智能决策】第十五章 智能推荐系统 - 协同过滤算法

第十五章 智能推荐系统 - 协同过滤算法 15.2 相似度计算三种常见方法 15.2.1 欧式距离 import pandas as pd df pd.DataFrame([[5, 1, 5], [4, 2, 2], [4, 2, 1]], columns[用户1, 用户2, 用户3], index[物品A, 物品B, 物品C]) df用户1用户2用户3物品A515物品B422物品C421 …

【AI大模型】SparkDesk讯飞星火认知大模型初体验-持续更新

文章目录 SparkDesk讯飞星火认知大模型简介语言理解知识问答逻辑推理数学题解答代码理解与编写写在最后 SparkDesk讯飞星火认知大模型简介 科大讯飞推出的新一代认知智能大模型&#xff0c;拥有跨领域的知识和语言理解能力&#xff0c;能够基于自然对话方式理解与执行任务。从海…

6.其他函数

1.时间日期类 -- current_date() 返回当前日期 -- date_add(date, n) 返回从date开始n天之后的日期 -- date_sub(date, n) 返回从date开始n天之前的日期 -- datediff(date1, date2) 返回date1-date2的日期差 -- year(date) 返回…

港联证券|“牛市旗手”频遭股东减持 机构仍看好板块后市表现

5月8日&#xff0c;证券板块再迎爆发。截至收盘&#xff0c;中国银河盘中触及涨停&#xff0c;收盘涨超7%&#xff0c;中银证券涨超5%&#xff0c;信达证券、光大证券、招商证券涨超4%。板块回暖之际&#xff0c;多家券商二季度却遭遇股东减持。业内人士认为&#xff0c;减持计…

算法--扫描线

写在前面&#xff1a; 这个算法理解还是挺好理解的&#xff0c;就是到后面解决面积并问题的时候开始难理解了&#xff0c;看了半天&#xff0c;主要是还有其他的知识没理解就开始搞这个了。虽然最后还是直接懂了。 文章目录 扫描线算法的介绍一维问题LintCode 391 数飞机题目…

【历史上的今天】5 月 9 日:中国黄页上线;Red Hat 创始人出生;Scratch 2.0 发布

整理 | 王启隆 透过「历史上的今天」&#xff0c;从过去看未来&#xff0c;从现在亦可以改变未来。 今天是 2023 年 5 月 9 日&#xff0c;在 1993 年的今天&#xff0c;第一届东亚运动会在上海隆重开幕&#xff0c;这是亚洲体育运动史上的新篇章。来自东亚地区的中国、日本、…

【笔记】【HTTP】《图解HTTP》第5章 与HTTP协做的Web服务器

前言 有输入就要有产出&#xff0c;该笔记是本人看完《图解HTTP》后对每章涉及到的知识进行汇总博客将会已书的每章为一篇发布&#xff0c;下一篇博客发布时间不确定笔记中有些个人理解后整理的笔记&#xff0c;可能有所偏差&#xff0c;也恳请读者帮忙指出&#xff0c;谢谢。…

信号signal编程测试

信号会打断系统调用&#xff0c;慎用&#xff0c;就是用的时候测一测。 下面是信号的基础测试 信号 信号&#xff08;signal&#xff09;机制是UNIX系统中最为古老的进程之间的通信机制。它用于在一个或多个进程之间传递异步信号。信号可以由各种异步事件产生&#xff0c;例如…

数据结构与算法1:引入概念

接下来系统的学一下数据结构与算法的知识&#xff0c;本章节是第一部分&#xff1a;数据结构与算法的进入与基本概述 第一章&#xff1a;引入概念 【铁打的算法demo】先来看到题&#xff1a; 如果 a b c 1000&#xff0c;且 a2 b2 c2&#xff08;a, b , c 为⾃然数&…

快进来,带你了解FPGA基础知识---lattice莱迪斯深力科MachXO2 FPGA系列简介

FPGA基础知识---lattice莱迪斯深力科MachXO2 LCMXO2-4000HC-4TG144I FPGA简介 FPGA基础知识&#xff1a;FPGA是英文Field&#xff0d;Programmable Gate Array的缩写&#xff0c;即现场可编程门阵列&#xff0c;它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。它…