Day38.C++提高03

Day38.C++提高03

01.函数对象(仿函数)

总结:

- 创建一个类,重载()
- 函数对象通常不定义构造函数和析构函数,所以在构造和析构时不会发生任何问题,避免了函数调用的运行时问题
- 函数对象超出普通函数的概念,可以在类中保存自己的状态。
- 函数对象可以内联编译,性能好
- 模板函数对象使函数对象具有通用性
- 函数对象可以作为函数参数来传递 

02.谓词(仿函数的返回值为bool类型)

概述:

- 谓词可分为一元谓词和二元谓词
- 一元谓词是指有一个参数,二元谓词有两个参数

代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>

class GreaterThen_20
{
public:

	bool operator()(int val)
	{
		return val > 20;
	}
};

//一元谓词
void test01()
{
	vector<int> v1;

	v1.push_back(10);
	v1.push_back(20);
	v1.push_back(30);
	v1.push_back(40);
	v1.push_back(50);
	v1.push_back(60);

	vector<int>::iterator pos = find_if(v1.begin(), v1.end(), GreaterThen_20());
	if (pos != v1.end())
	{
		cout << "找到第一个大于20的数为:" << *pos << endl;
	}
	else
	{
		cout << "没有找到" << endl;
	}
}

class MyCompare
{
public:

	bool operator()(int v1, int v2)
	{
		return v1 > v2;
	}
};

void test02()
{
	vector<int> v1;

	v1.push_back(10);
	v1.push_back(20);
	v1.push_back(30);
	v1.push_back(40);
	v1.push_back(50);
	v1.push_back(60);

	sort(v1.begin(), v1.end(), MyCompare());

	//匿名函数 lambda表达式 [](){}
	for_each(v1.begin(), v1.end(), [](int v) {cout << v << " "; });
}

int main(void)
{
	//test01();
	test02();

	system("pause");
	return EXIT_SUCCESS;
}

03.内建函数

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
//内建函数对象的头文件
#include<functional>

//算数类函数对象
void test01()
{
	//取反仿函数
	negate<int> n;
	cout << n(10) << endl;
	//加法仿函数
	plus<int> p;
	cout << p(10, 10) << endl;
}

//关系运算类函数对象
void test02()
{
	vector<int> v;
	v.push_back(10);
	v.push_back(20);
	v.push_back(30);
	v.push_back(40);
	v.push_back(50);
	v.push_back(60);

	//大于
	sort(v.begin(), v.end(), greater<int>());
	for_each(v.begin(), v.end(), [](int v) {cout << v << " "; });


}

int main(void)
{
	//test01();
	test02();

	system("pause");
	return EXIT_SUCCESS;
}

04.适配器

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<functional>

class printVector:public binary_function<int,int,void>
{
public:
	void operator()(int v, int start)const
	{
		cout << "v = " << v << "   start = " << start << "   v + start = " << v + start << endl;
	}
};

//函数适配器
//第一步绑定数据 利用bind2nd
//继承类 binary_function<参数类型1,参数类型2,返回值类型>
//加const 修饰operator()
void test01()
{
	vector<int> v;

	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}

	int num;
	cout << "请输入一个起始值:" << endl;
	cin >> num;

	//bind1st和bind2nd的区别
	//bind1st:将参数绑定为函数对象的第一个参数
	//bind2nd:将参数绑定为函数对象的第二个参数
	for_each(v.begin(), v.end(), bind2nd(printVector(),num));
	//for_each(v.begin(), v.end(), bind1st(printVector(),num));


}

class GreaterThenFive:public unary_function<int,bool>
{
public:
	bool operator()(int v)const
	{
		return v > 5;
	}
};

//取反适配器
//一元取反适配器 not1
//继承unary_function<参数类型1,返回值类型>
//const 修饰
void test02()
{
	//一元取反
	vector<int> v;
	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}

	//查找大于5的数字
	vector<int>::iterator pos1 = find_if(v.begin(), v.end(), GreaterThenFive());
	//查找小于5的数字
	vector<int>::iterator pos2 = find_if(v.begin(), v.end(), not1(GreaterThenFive()));
	//find_if(v.begin(), v.end(), not1(bind2nd(greater<int>(), 5)));//比较复杂的一种方法

	if (pos1 != v.end())
	{
		cout << "第一个大于5的数字为:" << *pos1 << endl;
	}
	else
	{
		cout << "没找到大于5的数字" << endl;
	}
	
	if (pos2 != v.end())
	{
		cout << "第一个小于5的数字为:" << *pos2 << endl;
	}
	else
	{
		cout << "没找到小于5的数字" << endl;
	}

}

void MyPrint03(int v,int start)
{
	cout << v + start << " ";
}

//函数指针适配器
void test03()
{
	vector<int> v;
	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}
	//将函数指针适配为 函数对象
	//ptr_fun
	for_each(v.begin(), v.end(), bind2nd(ptr_fun(MyPrint03), 100));
}

class Person
{
public:

	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

	void showPerson()
	{
		cout << "姓名:" << this->m_Name << "  年龄:" << this->m_Age << endl;
	}

	void agePlus()
	{
		this->m_Age++;
	}

	string m_Name;
	int m_Age;
};

//成员函数适配器
void test04()
{
	vector<Person> v;

	Person p1("aaa", 10);
	Person p2("bbb", 20);
	Person p3("ccc", 30);
	Person p4("ddd", 40);

	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);
	
	//成员函数适配器
	//mem_fun_ref
	for_each(v.begin(), v.end(), mem_fun_ref(&Person::showPerson));
	for_each(v.begin(), v.end(), mem_fun_ref(&Person::agePlus));
	for_each(v.begin(), v.end(), mem_fun_ref(&Person::showPerson));

}

int main(void)
{
	//test01();
	//test02();
	//test03();
	test04();

	system("pause");
	return EXIT_SUCCESS;
}

05.常用的遍历算法(for_each,transform)

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<algorithm>
#include<vector>
#include<functional>

/*
遍历算法  遍历容器元素
@param beg   开始迭代器
@param end   结束迭代器
@param _callback   函数回调或者函数对象
@return      函数对象
*/

void test01()
{
	vector<int> v;
	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}

	for_each(v.begin(), v.end(), [](int v) {cout << v << " "; });

}

struct myPrint02
{
	void operator()(int v)
	{
		cout << v << endl;
		this->m_Count++;
	}
	int m_Count;
};
//for_each有返回值
//可以保存内部记录
void test02()
{
	vector<int> v;
	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}

	//for_each是有返回值的,返回值为调用的函数对象
	myPrint02 print2 = for_each(v.begin(), v.end(), myPrint02());
	cout << "print2.m_Count:" << print2.m_Count << endl;
}

struct myPrint03:public binary_function<int,int,void>
{
	void operator()(int v,int start)const
	{
		cout << v + start << endl;
	}
};
//for_each可以绑定参数进行输出
void test03()
{
	vector<int> v;
	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}

	for_each(v.begin(), v.end(), bind2nd(myPrint03(), 1000));
}


//transform算法  将指定容器区间元素搬运到另一容器中
//注:transform 不会给目标容器分配内存,所以需要我们提前分配好内存

class Transform
{
public:
	int operator()(int val)
	{
		return val + 10;
	}
};

void test04()
{
	vector<int> v;
	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}

	vector<int> vTarget;
	vTarget.resize(v.size());

	transform(v.begin(), v.end(), vTarget.begin(), Transform());

	for_each(vTarget.begin(), vTarget.end(), [](int v) {cout << v << endl; });

}

//tansform 的第二种用法 将两个容器数据相加搬运到目标容器
class Transform2
{
public:
	int operator()(int val1,int val2)
	{
		return val1 + val2;
	}
};
void test05()
{
	vector<int> v1;
	vector<int> v2;
	for (int i = 0; i < 10; ++i)
	{
		v1.push_back(i + 100);
		v2.push_back(i + 1000);
	}

	vector<int> vTarget;
	vTarget.resize(v1.size());

	transform(v1.begin(), v1.end(), v2.begin(), vTarget.begin(), Transform2());
	for_each(vTarget.begin(), vTarget.end(), [](int v) {cout << v << endl; });
}


int main(void)
{
	//test01();
	//test02();
	//test03();
	//test04();
	test05();

	system("pause");
	return EXIT_SUCCESS;
}

06.常用的查找算法

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<algorithm>
#include<vector>
#include<string>
#include<functional>


//find()
void test01()
{
	vector<int> v;
	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i + 1);
	}

	vector<int>::iterator pos = find(v.begin(), v.end(), 5);
	if (pos != v.end())
	{
		cout << "找到了数字" << *pos << endl;
	}
	else
	{
		cout << "没找到" << endl;
	}
}

//利用find查找自定义数据类型
class Person
{
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

	bool operator==(const Person& p)const
	{
		if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
		{
			return true;
		}
		return false;
	}

	string m_Name;
	int m_Age;
};

void test02()
{
	vector<Person> v;

	Person p1("aaa", 10);
	Person p2("bbb", 20);
	Person p3("ccc", 30);
	Person p4("ddd", 40);
	Person p5("eee", 50);
	Person p6("fff", 60);

	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);
	v.push_back(p5);
	v.push_back(p6);

	vector<Person>::iterator pos = find(v.begin(), v.end(), p3);

	if (pos != v.end())
	{
		cout << "找到了,姓名:" << (*pos).m_Name << "  年龄:" << (*pos).m_Age << endl;
	}
	else
	{
		cout << "没找到" << endl;
	}
}

class myCompare:public binary_function<const Person*, const Person*, bool>
{
public:

	bool operator()(const Person* p1, const Person* p2)const
	{
		if (p1->m_Name == p2->m_Name && p1->m_Age == p2->m_Age)
		{
			return true;
		}
		return false;
	}
};

void test03()
{
	vector<Person*> v;

	Person p1("aaa", 10);
	Person p2("bbb", 20);
	Person p3("ccc", 30);
	Person p4("ddd", 40);
	Person p5("eee", 50);
	Person p6("fff", 60);

	v.push_back(&p1);
	v.push_back(&p2);
	v.push_back(&p3);
	v.push_back(&p4);
	v.push_back(&p5);
	v.push_back(&p6);

	Person* p = new Person("bbb", 20);

	vector<Person*>::iterator pos = find_if(v.begin(), v.end(), bind2nd(myCompare(),p));

	if (pos != v.end())
	{
		cout << "找到了,姓名:" << (*pos)->m_Name << "  年龄:" << (*pos)->m_Age << endl;
	}
	else
	{
		cout << "没找到" << endl;
	}
}


//adjacent_find算法 查找相邻重复元素
//返回相邻元素的第一个位置的迭代器
void test04()
{
	vector<int>v;
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(5);
	v.push_back(6);
	v.push_back(2);

	vector<int>::iterator pos = adjacent_find(v.begin(), v.end());

	if (pos != v.end())
	{
		cout << "找到了相邻重复元素为:" << *pos << endl;
	}
	else
	{
		cout << "未找到" << endl;
	}
}


//binary_search算法 二分查找法
//注:在无序序列中不可用
void test05()
{
	vector<int> v;
	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}

	bool ret = binary_search(v.begin(), v.end(), 4);
	if (ret)
	{
		cout << "找到了" << endl;
	}
	else
	{
		cout << "未找到" << endl;
	}
}


//count 算法 和count_if 算法 统计元素出现的次数
//返回元素个数 int

class GreaterThenFour
{
public:

	bool operator()(int val)
	{
		return val > 4;
	}
};

void test06()
{
	vector<int> v;
	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}

	v.push_back(3);
	v.push_back(3);
	v.push_back(3);
	v.push_back(3);
	v.push_back(3);

	int num = count(v.begin(), v.end(), 3);
	cout << "3的个数为:" << num << endl;

	int num1 = count_if(v.begin(), v.end(), GreaterThenFour());
	cout << "大于4的元素个数:" << num1 << endl;
}




int main(void)
{
	//test01();
	//test02();
	//test03();
	//test04();
	//test05();
	test06();
	system("pause");
	return EXIT_SUCCESS;
}

07.常用的排序算法

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<ctime>


//merge算法 容器元素合并,并存储到另一个容器中,
//这两个容器 必须也是有序的,并且排序规则也需要相同

void test01()
{
	vector<int> v1;
	vector<int> v2;

	for (int i = 0; i < 10; ++i)
	{
		v1.push_back(i);
		v2.push_back(2 * i);
	}
	vector<int> vTarget;
	vTarget.resize(v1.size() + v2.size());

	merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());

	for_each(vTarget.begin(), vTarget.end(), [](int v) {cout << v << " "; });
}

//sort 算法 容器元素排序
void test02()
{
	vector<int> v1;
	
	v1.push_back(10);
	v1.push_back(30);
	v1.push_back(20);
	v1.push_back(40);
	v1.push_back(50);

	sort(v1.begin(), v1.end());
	for_each(v1.begin(), v1.end(), [](int v) {cout << v << " "; });
	cout << endl;

	sort(v1.begin(), v1.end(), greater<int>());
	for_each(v1.begin(), v1.end(), [](int v) {cout << v << " "; });
	cout << endl;
}

//random_shuffle(iterator beg, iterator end)  洗牌算法
void test03()
{
	vector<int> v;

	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}
	random_shuffle(v.begin(), v.end());
	for_each(v.begin(), v.end(), [](int v) {cout << v << " "; });
	cout << endl;
}

//reverse  算法 反转
void test04()
{
	vector<int> v;

	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}
	reverse(v.begin(), v.end());
	for_each(v.begin(), v.end(), [](int v) {cout << v << " "; });
	cout << endl;
}

int main(void)
{
	srand((unsigned int)time(NULL));
	//test01();
	//test02();
	//test03();
	test04();

	system("pause");
	return EXIT_SUCCESS;
}

08.常用的拷贝和替换算法

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<iterator>


//copy算法 将容器内指定范围的元素拷贝到另一个容器中
void test01()
{
	vector<int>v;
	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}

	vector<int>vTarget;
	vTarget.resize(v.size());
	copy(v.begin(), v.end(), vTarget.begin());

	for_each(vTarget.begin(), vTarget.end(), [](int v) {cout << v << " "; });
}

//replace算法 将容器内指定范围的旧元素修改为新元素
//replace_if 算法  将容器内指定范围内满足条件的元素替换为新元素

class GreaterThen3
{
public:
	bool operator()(int val)
	{
		return val > 3;
	}
};

void test02()
{
	vector<int>v;
	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}
	//将容器中所有3都替换成300
	replace(v.begin(), v.end(), 3, 300);

	//将容器中的元素copy到输出流中进行输出打印
	copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
	cout << endl;

	//将容器中所有大于3的数都替换成3000
	replace_if(v.begin(), v.end(), GreaterThen3(), 3000);
	copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));

}

//swap算法 交换两个容器中的元素
void test03()
{
	vector<int>v1;
	vector<int>v2;
	for (int i = 0; i < 10; ++i)
	{
		v1.push_back(i);
	}
	v2.push_back(10);
	v2.push_back(20);
	v2.push_back(30);
	v2.push_back(40);

	cout << "交换前:" << endl;
	copy(v1.begin(), v1.end(), ostream_iterator<int>(cout, " "));
	cout << endl;
	copy(v2.begin(), v2.end(), ostream_iterator<int>(cout, " "));
	cout << endl;

	swap(v1, v2);

	cout << "交换后:" << endl;
	copy(v1.begin(), v1.end(), ostream_iterator<int>(cout, " "));
	cout << endl;
	copy(v2.begin(), v2.end(), ostream_iterator<int>(cout, " "));
	cout << endl;
}

int main(void)
{
	//test01();
	//test02();
	test03();

	system("pause");
	return EXIT_SUCCESS;
}

09.常用的算数生成算法

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<vector>
//accumulate 和fill 算法, 需要导入的头文件
#include<numeric>
#include<iterator>

//accumulate算法  计算容器元素累计总和
void test01()
{
	vector<int> v;
	for (int i = 0; i <= 100; ++i)
	{
		v.push_back(i);
	}
	//0~100 的累加和
	//第三个参数 起始累加值
	int sum = accumulate(v.begin(), v.end(), 0);
	cout << " 总和为:" << sum << endl;
}


//fill 算法,向容器中添加元素
void test02()
{
	vector<int> v;
	v.resize(10);

	fill(v.begin(), v.end(), 1000);

	copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
}

int main(void)
{
	//test01();
	test02();
	system("pause");
	return EXIT_SUCCESS;
}

10.常用的集合算法(交际 并集 差集)

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<iterator>

//set_intersection 算法 求两个 set 集合的交集
//注意:两个集合必须是有序序列
void test01()
{
	vector<int> v1;
	vector<int> v2;
	for (int i = 0; i < 10; ++i)
	{
		v1.push_back(i);
		v2.push_back(i + 5);
	}
	vector<int> vTarget;
	vTarget.resize(min(v1.size(), v2.size()));

	vector<int>::iterator itEnd = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());

	copy(vTarget.begin(), itEnd, ostream_iterator<int>(cout, " "));
	
}


//set_union 算法  求两个 set 集合的并集
//注意:两个集合必须是有序序列
void test02()
{
	vector<int> v1;
	vector<int> v2;
	for (int i = 0; i < 10; ++i)
	{
		v1.push_back(i);
		v2.push_back(i + 5);
	}
	vector<int> vTarget;
	vTarget.resize(v1.size() + v2.size());

	vector<int>::iterator itEnd = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());

	copy(vTarget.begin(), itEnd, ostream_iterator<int>(cout, " "));

}


//set_difference 算法 求两个 set 集合的差集
//注意:两个集合必须是有序序列
void test03()
{
	vector<int> v1;
	vector<int> v2;
	for (int i = 0; i < 10; ++i)
	{
		v1.push_back(i);
		v2.push_back(i + 5);
	}
	vector<int> vTarget;

	cout << "v1差v2" << endl;
	
	vTarget.resize(v1.size());
	vector<int>::iterator itEnd = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
	copy(vTarget.begin(), itEnd, ostream_iterator<int>(cout, " "));

	cout << endl << "v2差v1" << endl;

	vTarget.resize(v2.size());
	itEnd = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), vTarget.begin());
	copy(vTarget.begin(), itEnd, ostream_iterator<int>(cout, " "));
}

int main(void)
{
	//test01();
	//test02();
	test03();

	system("pause");
	return EXIT_SUCCESS;
}

11.演讲比赛案例

比赛规则:

- 某市举行一场演讲比赛(speech_contest),共有24个人参加。比赛共三轮,前两轮为淘汰赛,第三轮为决赛。
- 比赛方式:分组比赛,每组6个人,选手每次要随机分组,进行比赛
- 第一轮分为4个小组,每组6个人。比如编号为:100-123.整体进行抽签(draw)后顺序演讲。当小组演讲完后,淘汰组内排名最后的三个选手,然后继续下一个小组的比赛。
- 第二轮分为两个小组,每组6个人。比赛完毕,淘汰组内排名最后的三个选手,然后继续下一个小组的比赛。
- 第三轮只剩下1组6个人,本轮为决赛,选出前三名。
- 比赛评分:10个评委打分,去除最低、最高分,求平均分。每个选手演讲完由10个评委分别打分。

- 用STL编程,求解这个问题
- (1)请打印出所有选手的名字与参赛号,并以参赛号的升序排列
- (2)打印每一轮比赛后,小组比赛成绩和小组晋级名单

需求分析:

(1)产生选手(ABCDEFGHIJKLMNOPQRSTUVWX)姓名、得分、选手编号
(2)第一轮  选手抽签 选手比赛 查看比赛结果 
(3)第二轮  选手抽签 选手比赛 查看比赛结果
(4)第三轮  选手抽签 选手比赛 查看比赛结果

实现思路:

需要把选手信息、选手得分信息、选手比赛抽签信息、选手的晋级信息、选手的晋级信息保存在容器中,需要涉及到各个容器的选型。
选手可以设计一个类Speaker(姓名和得分)
所有选手的编号可以单独放在一个vector容器中,做抽签用
所有选手编号和选手信息,可以放在容器内:map<int,Sperker>

实现代码:

Speaker.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<string>
#include<iostream>
using namespace std;

class Speaker
{
public:

	Speaker(string name, int number,int s1,int s2, int s3);
	string getName()const;
	int getScore(int i)const;//i代表第i轮比赛
	int getNum()const;
	void setScore(int i, int score);
	void setNum(int num);


private:
	string m_Name;
	int m_Score[3];
	int m_Number;
};

Speaker.cpp

#include"Speaker.h"

Speaker::Speaker(string name, int number, int s1, int s2, int s3)
{	
	this->m_Name = name;
	this->m_Number = number;
	this->m_Score[0] = s1;
	this->m_Score[1] = s2;
	this->m_Score[2] = s3;	
}

string Speaker::getName()const
{
	return this->m_Name;
}

int Speaker::getScore(int i)const
{
	return this->m_Score[i];
}

void Speaker::setScore(int i,int score)
{
	this->m_Score[i] = score;
}

int Speaker::getNum()const
{
	return this->m_Number;
}

void Speaker::setNum(int num)
{
	this->m_Number = num;
}

演讲比赛案例.cpp

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<string>
#include<ctime>
#include<vector>
#include<map>
#include<algorithm>
#include<deque>
#include<numeric>
#include"Speaker.h"


//获取24名参赛选手的信息
void getSpeaker(map<int, Speaker>& m, vector<int>& v)
{
	string speakerSeed = "ABCDEFGHIJKLMNOPQRSTUVWX";
	string name;
	int num;
	for (int i = 0; i < 24; ++i)
	{
		name = string("Speaker") += speakerSeed[i];
		num = i + 100;
		v.push_back(num);
		m.insert(pair<int, Speaker>(num, Speaker(name, num, 0, 0, 0)));	
	}
}

//打印选手信息
void showSpeaker(const map<int, Speaker>& m)
{
	cout << "=============================24名选手上场================================" << endl;
	cout << endl;
	for (map<int, Speaker>::const_iterator it = m.begin(); it != m.end(); it++)
	{
		cout << "选手姓名:" << (*it).second.getName() << "   选手编号:" << (*it).second.getNum() << endl;
	}
}

//抽签决定分组及其表演顺序
void drawLots(vector<int>& v, vector<vector<int>>& vGro)
{
	//清空存放分组信息的容器
	vGro.resize(0);
	//洗牌算法,打乱存放编号的容器中元素的顺序
	random_shuffle(v.begin(), v.end());
	
	//创建一个临时的容器存放每一组的选手编号
	vector<int> vEveGro;

	//初始化迭代器
	vector<int>::iterator beg = v.begin();
	vector<int>::iterator end = v.begin() + 6;

	//将每一组的选手编号存放在 选手分组容器中
	for (int i = 0; i < (v.size() / 6); ++i)
	{
		for (vector<int>::iterator it = beg; it != end; it++)
		{
			vEveGro.push_back(*it);
		}
		vGro.push_back(vEveGro);

		vEveGro.resize(0);
		/*for (int i = 0; i < 6; ++i)
		{
			vEveGro.pop_back();
		}*/
		if (end != v.end())
		{
			beg = beg + 6;
			end = end + 6;
		}		
	}
}


//打印比赛信息,最后一个参数是比赛的轮数
void ShowGame(map<int, Speaker>& m, vector<vector<int>>& vGro, vector<int>& v,int GameOfNum)
{
	//临时变量 存放正在比赛的组号
	int i = 1;
	//临时变量 存放每名评委给选手的评分
	int s;
	//临时容器 存放十名评委给的评分
	deque<int> d;
	//临时变量 存放选手的最终成绩
	int score;
	//保存选手编号和分数,用于打印淘汰信息
	map<int, int> mEveSp;
	
	for (vector<vector<int>>::iterator it = vGro.begin(); it != vGro.end(); it++)
	{
		cout << "=========================================================================" << endl;
		cout << "第" << i << "组比赛开始:" << endl;
		cout << "=========================================================================" << endl;

		for (vector<int>::iterator itNum = (*it).begin(); itNum != (*it).end(); itNum++)
		{
			cout << m.find((*itNum))->second.getName() << "  开始演讲!!" << endl;
			cout << "吧啦吧啦=============================================================" << endl;
			cout << "十名评委给该选手打分:" << endl;
			
			//给选手打分
			for (int j = 0; j < 10; ++j)
			{
				s = rand() % 100 + 1;
				cout << s << " ";
				d.push_back(s);
			}
			cout << endl;
			sort(d.begin(), d.end());
			d.pop_back();
			d.pop_front();
			score = (accumulate(d.begin(), d.end(), 0)) / 8;
			d.resize(0);

			cout << "去掉一个最高分,去掉一个最低分,最终成绩为:" << score << endl;
			cout << "有请下一位选手。" << endl;
			cout << endl;
			cout << endl;
			
			//保存选手分数
			m.find((*itNum))->second.setScore(GameOfNum - 1, score);
			//保存选手分数和编号
			mEveSp.insert(pair<int, int>(score, m.find((*itNum))->first));
		}
		cout << "第" << i << "组选手演讲完毕!!" << endl;

		map<int, int>::iterator itEveSp = mEveSp.begin();
		for (int i = 0; i < 3; ++i)
		{
			cout << m.find((*itEveSp).second)->second.getName() << "被淘汰" << endl;
			m.erase((*itEveSp).second);
			itEveSp++;
		}
		mEveSp.clear();
		i++;
	}

	v.resize(0);
	for (map<int, Speaker>::iterator it = m.begin(); it != m.end(); it++)
	{
		v.push_back((*it).first);
	}
}

class myCompare
{
public:

	bool operator()(const Speaker& s1,const Speaker& s2)
	{
		return s1.getScore(2) > s2.getScore(2);
	}
};

int main(void)
{
	srand((unsigned int)time(NULL));

	vector<int> vNum;//存放选手的编号
	map<int, Speaker> mSpeaker;//存放选手和选手编号
	vector<vector<int>> vGroup;//存放分组信息
	int key;

	//产生24名选手,并存信息到容器中
	getSpeaker(mSpeaker, vNum);
	//打印24名选手上场名单
	showSpeaker(mSpeaker);
	
	/*cout << "按数字键加回车继续比赛:";
	cin >> key;*/
	
	//第一次抽签分组
	drawLots(vNum, vGroup);
	//第一次分组表演,产生分数
	ShowGame(mSpeaker, vGroup, vNum, 1);

	/*cout << "按数字键加回车继续比赛:";
	cin >> key;*/
	
	//第二次抽签分组,分组表演,产生分数
	drawLots(vNum, vGroup);
	ShowGame(mSpeaker, vGroup, vNum, 2);

	//cout << "按数字键加回车继续比赛:";
	//cin >> key;

	//第三次抽签分组,分组表演,产生分数
	drawLots(vNum, vGroup);
	ShowGame(mSpeaker, vGroup, vNum, 3);

	//打印冠军 亚军 季军
	vector<Speaker> vSpeaker;
	for (int i = 0; i < 3; ++i)
	{
		vSpeaker.push_back(mSpeaker.find(*(vNum.begin() + i))->second);
	}

	sort(vSpeaker.begin(), vSpeaker.end(), myCompare());

	vector<Speaker>::iterator itSp = vSpeaker.begin();
	for (int i = 0; i < 3; ++i)
	{
		switch (i)
		{
		case 0:
			cout << "冠军是:" << endl;
			break;
		case 1:
			cout << "亚军是:" << endl;
			break;
		case 2:
			cout << "季军是:" << endl;
			break;
		default:
			break;
		}
		
		cout << "选手姓名:" << (*itSp).getName() << "     选手编号:" << (*itSp).getNum() << endl;
		itSp++;

	}

	system("pause");
	return EXIT_SUCCESS;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值