在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理C++知识点的第三十三篇博客。
本篇博客用C++实现了演讲比赛流程管理系统,本文是下半部分。
本系列博客所有C++代码都在Visual Studio 2022环境下编译运行。程序为64位。
目录
演讲比赛流程管理系统
抽签功能实现
void speechmanager::draw_speaker()
{
if (index == 1) {
random_shuffle(v1.begin(), v1.end());
cout << "The people in first round is " << endl;
for (vector<int>::iterator it = v1.begin(); it != v1.end(); ++it) {
cout << "The number is " << *it << " " << " and the name is " << m.find(*it)->second.name << endl;
}
cout << endl;
}
else if (index == 2)
{
cout << "The people in second round is " << endl;
random_shuffle(v2.begin(), v2.end());
for (vector<int>::iterator it = v2.begin(); it != v2.end(); ++it) {
cout << "The number is " << *it << " " << " and the name is " << m.find(*it)->second.name << endl;
}
cout << endl;
}
}
draw_speaker成员函数实现抽签。如果是第一轮(index代表轮数),就随机对v1进行洗牌,输出洗牌后的结果。实际上没有创建新容器,而是将洗牌后前六个作为第一组,后六个作为第二组。如果是第二轮,就对v2进行洗牌,输出洗牌后的结果。
比赛功能实现
void speechmanager::speech_contest()
{
if (index == 1) {
cout << "The first round" << endl;
int num = 1;
multimap<double, int, greater<double>> mm;
for (vector<int>::iterator it = v1.begin(); it != v1.end(); ++it) {
deque<double> score;
int i;
for (i = 0; i < 10; i += 1) {
int rscore = rand() % 401 + 600;
double result = rscore % 10;
score.push_back(rscore);
}
sort(score.begin(), score.end(), greater<double>());
score.pop_back();
score.pop_front();
double average = accumulate(score.begin(), score.end(), 0) / 8.0;
mm.insert(make_pair(average, *it));
if (num == 6) {
cout << "The first group" << endl;
int n = 1;
for (multimap<double, int, greater<double>>::iterator ite = mm.begin(); ite != mm.end(); ++ite) {
cout << "The number is " << ite->second << " and the name is " << m.find(ite->second)->second.name << " and the score is " << ite->first << endl;
m.find(ite->second)->second.scorea = ite->first;
if (n <= 3) {
v2.push_back(ite->second);
}
n += 1;
}
mm.clear();
}
if (num == 12) {
cout << "The second group" << endl;
int n = 1;
for (multimap<double, int, greater<double>>::iterator ite = mm.begin(); ite != mm.end(); ++ite) {
cout << "The number is " << ite->second << " and the name is " << m.find(ite->second)->second.name << " and the score is " << ite->first << endl;
m.find(ite->second)->second.scorea = ite->first;
if (n <= 3) {
v2.push_back(ite->second);
}
n += 1;
}
mm.clear();
}
num += 1;
}
}
else if (index == 2)
{
cout << "The second round" << endl;
multimap<double, int, greater<double>> mm;
for (vector<int>::iterator it = v2.begin(); it != v2.end(); ++it) {
deque<double> score;
int i;
for (i = 0; i < 10; i += 1) {
int rscore = rand() % 401 + 600;
double result = rscore % 10;
score.push_back(rscore);
}
sort(score.begin(), score.end(), greater<double>());
score.pop_back();
score.pop_front();
double average = accumulate(score.begin(), score.end(), 0) / 8.0;
mm.insert(make_pair(average, *it));
}
int n = 1;
for (multimap<double, int, greater<double>>::iterator ite = mm.begin(); ite != mm.end(); ++ite) {
cout << "The number is " << ite->second << " and the name is " << m.find(ite->second)->second.name << " and the score is " << ite->first << endl;
m.find(ite->second)->second.scoreb = ite->first;
if (n <= 3) {
v3.push_back(ite->second);
}
n += 1;
}
mm.clear();
}
}
在第一轮,先输出提示信息,然后创建一个multimap容器mm,mm的键表示成绩,值表示编号,排序按降序排序。然后创建一个循环,遍历v1,对于每个成员,都按照前面的去掉最高分和最低分后取剩下的平均分的规则,得到平均分,然后和编号一起作为键值对加入mm。每次循环后num加一。(num在循环开始前初始化为1)。在num加一前,对num的值进行判断,如果是6或12(此时代表已经遍历了6或12个)就进行特殊操作。
当num值为6时,输出表明是第一组成绩,随后遍历输出mm的元素,并将前三个的编号加入v2。随后清空mm。当num值为12时,输出表明是第二组成绩,随后遍历输出mm的元素,将前三个的编号加入v2,并清空mm。
在第二轮,先输出提示信息,然后创建一个multimap容器mm,mm的键表示成绩,值表示编号,排序按降序排序。然后创建一个循环,遍历v2,对于每个成员,都按照前面的去掉最高分和最低分后取剩下的平均分的规则,得到平均分,然后和编号一起作为键值对加入mm。然后遍历mm,输出相关信息,前三个加入v3后清空mm。
显示晋级选手信息
void speechmanager::start_contest()
{
index = 1;
draw_speaker();
system("pause");
speech_contest();
system("pause");
cout << "The people in second round is " << endl;
for (vector<int>::iterator it = v2.begin(); it != v2.end(); ++it) {
cout << "The number is " << *it << " " << " and the name is " << m.find(*it)->second.name << endl;
}
cout << endl;
system("pause");
system("cls");
index = 2;
draw_speaker();
system("pause");
speech_contest();
system("pause");
cout << "The people of victorious is " << endl;
for (vector<int>::iterator it = v3.begin(); it != v3.end(); ++it) {
cout << "The number is " << *it << " " << " and the name is " << m.find(*it)->second.name << endl;
}
cout << endl;
system("pause");
save_result();
cout << "The contest has ended" << endl;
system("pause");
system("cls");
}
start_contest成员函数实现了流程功能和晋级选手信息输出。首先将index置为1,然后首先调用draw_speaker函数,再调用speech_contest成员函数,再输出第一轮选手晋级信息。随后首先将index置为2,然后首先调用draw_speaker函数,再调用speech_contest成员函数。然后输出获胜的选手信息,存入文件中,提示比赛结束。
保存分数
void speechmanager::save_result()
{
ofstream ofs;
ofs.open("speechresult.csv", ios::out | ios::app);
for (vector<int>::iterator it = v3.begin(); it != v3.end(); ++it) {
ofs << *it << "," << m.find(*it)->second.name << "," << m.find(*it)->second.scoreb << endl;
}
ofs.close();
}
save_result成员函数将v3的信息按照一定格式存入文件中。(前面在比赛流程中已经修改了所有对象scorea和scoreb成员变量)
获取往届分数
void speechmanager::read_result()
{
ifstream ifs;
ifs.open("speechresult.csv", ios::in);
if (ifs.is_open() == false) {
cout << "The file does not exist" << endl;
return;
}
char ch;
ifs >> ch;
if (ifs.eof() == true) {
cout << "It is blank" << endl;
return;
}
ifs.putback(ch);
int number = 1;
while (true) {
bool flag = true;
for (int i = 0; i < 3; i += 1) {
vector<string> vs;
string s;
getline(ifs, s);
int pos = -1;
int start = 0;
pos = s.find(",", start);
if (pos != -1) {
string strtemp1 = s.substr(start, pos - start);
vs.push_back(strtemp1);
}
else {
flag = false;
break;
}
start = pos + 1;
pos = s.find(",", start);
if (pos != -1) {
string strtemp2 = s.substr(start, pos - start);
vs.push_back(strtemp2);
}
string strtemp3 = s.substr(pos + 1, s.size() - 1);
vs.push_back(strtemp3);
if (i == 0) {
cout << "The " << number << " contest result" << endl;
}
cout << "The " << i + 1 << " place:" << endl;
cout << "number: " << vs[0] << " name: " << vs[1] << " score: " << vs[2] << endl;
}
if (flag == false) {
break;
}
number += 1;
}
ifs.close();
system("pause");
system("cls");
}
程序首先检查文件是否存在,不存在提示文件为空并结束函数。然后检查是否有内容,无内容就提示为空并结束函数。然后进入大循环,条件是true,大循环内定义了bool类型变量flag,默认为true,为false就退出循环。小循环会执行三次,代表一届比赛的前三名,每次读取一行内容。将内容按照格式碎开,随后输出。每次小循环结束将number(循环外定义,初始值为1)加一,代表记录的届数加一。读到内容结束时就将flag置为false并退出小循环。
清空记录功能实现
void speechmanager::clear_result()
{
int select;
cout << "Do you want to clear all of the results?";
cout << "Please press 0 to confirm" << endl;
cin >> select;
if (select == 0) {
ofstream ofs("speechresult.csv", ios::trunc);
cout << "Done" << endl;
init_speaker();
}
system("pause");
system("cls");
}
clear_result函数实现清空功能。首先提示是否清空,按0表示清空。然后输入不是0就结束函数。否则,将文件清空,提示已清空。
另外,speechmanager类的析构函数是空实现。
演讲比赛流程管理系统已经结束了,主要是理清流程,注意容器的选用。