C++ STL标准库 中篇

01.stack容器(了解)

1.数据结构:连续的存储空间,只有一个出口,先进后出特性

2.迭代器:没有迭代器

3.常用的api:

​ 1.构造函数

​ 2.赋值

​ 3.数据存取

​ 3.大小操作

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

//栈容器,先进后出
//存储基础数据类型
void test01()
{
	stack<int> s;
	s.push(10);
	s.push(20);
	s.push(30);
	s.push(40);
	s.push(50);

	//输出栈中元素
	while (!s.empty())
	{
		//输出栈顶元素
		cout << s.top() << " ";
		//弹出栈顶元素
		s.pop();
	}
	cout << "size:" << s.size() << endl;
}

class Maker
{
public:
	Maker(string name, int age)
	{
		this->name = name;
		this->age = age;
	}
public:
	string name;
	int age;
};
//存储对象
void test02()
{
	stack<Maker> s;
	s.push(Maker("aaa", 18));
	s.push(Maker("bbb", 19));
	s.push(Maker("ccc", 20));

	while (!s.empty())
	{
		cout << "Name:" << s.top().name << " Age:" << s.top().age << endl;
		s.pop();
	}
	
}

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

02.queue容器(了解)

1.数据结构:连续的存储空间,有两个口,一个是进入数据,一个是出数据,有先进先出的特性

2.迭代器:没有迭代器

3.常用的api:

​ 1.构造函数

​ 2.存取、插入和删除操作

​ 3.赋值

​ 4.大小操作

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

void test01()
{
	queue<int> q;
	for (int i = 0; i < 5; i++)
	{
		q.push(i + 1);
	}
	cout << "front:" << q.front() << endl;
	cout << "back:" << q.back() << endl;

	while (!q.empty())
	{
		cout << q.front() << " ";
		q.pop();

	}
	cout << endl;
	cout << q.size() << endl;
}


class Maker
{
public:
	Maker(string name, int age)
	{
		this->name = name;
		this->age = age;
	}
public:
	string name;
	int age;
};

void test02()
{
	queue<Maker*> q;
	q.push(new Maker("aaa", 18));
	q.push(new Maker("bbb", 19));
	q.push(new Maker("ccc", 20));

	while (!q.empty())
	{
		Maker* m = q.front();
		cout << m->name << " " << m->age << endl;
		q.pop();
		delete m;

	}

}

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

03.list容器(重点难点)

1.数据结构:双向循环链表

2.迭代器:双向迭代器

3.常用的api:

​ 1.构造

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

void printList(const list<int> &mylist)
{
	for (list<int>::const_iterator it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}
/*
构造
list<T> lstT;//list采用采用模板类实现,对象的默认构造形式:
list(beg,end);//构造函数将[beg, end)区间中的元素拷贝给本身。
list(n,elem);//构造函数将n个elem拷贝给本身。
list(const list &lst);//拷贝构造函数。

*/
void test01()
{
	list<int> mylist1(10, 6);
	list<int> mylist2(++mylist1.begin(), --mylist1.end());

	printList(mylist2);
}

​ 2.数据元素的插入和删除

/*
数据元素插入和删除操作
push_back(elem);//在容器尾部加入一个元素
pop_back();//删除容器中最后一个元素
push_front(elem);//在容器开头插入一个元素
pop_front();//从容器开头移除第一个元素
insert(pos,elem);//在pos位置插elem元素的拷贝,返回新数据的位置。
insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。
clear();//移除容器的所有数据
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
erase(pos);//删除pos位置的数据,返回下一个数据的位置。
remove(elem);//删除容器中所有与elem值匹配的元素。

*/

bool myfunc(int val)
{
	return val > 300;
}
void test02()
{
	list<int> mylist;
	mylist.push_back(10);
	mylist.push_back(20);
	mylist.push_back(30);
	mylist.push_back(40);
	mylist.push_back(50);
	mylist.push_front(100);
	mylist.push_front(200);
	mylist.push_front(300);
	mylist.push_front(400);

	vector<int> v;
	v.push_back(1000);
	v.push_back(2000);
	v.push_back(3000);

	mylist.insert(mylist.begin(), v.begin(), v.end());

	printList(mylist);

	mylist.remove(300);

	printList(mylist);

	//要删除大于300的数据
	mylist.remove_if(myfunc);
	printList(mylist);
}

​ 3.大小操作

/*
大小操作
size();//返回容器中元素的个数
empty();//判断容器是否为空
resize(num);//重新指定容器的长度为num,
若容器变长,则以默认值填充新位置。
如果容器变短,则末尾超出容器长度的元素被删除。
resize(num, elem);//重新指定容器的长度为num,
若容器变长,则以elem值填充新位置。
如果容器变短,则末尾超出容器长度的元素被删除。

*/
void test03()
{
	list<int> mylist;
	for (int i = 0; i < 5; i++)
	{
		mylist.push_back(i + 1);
	}

	cout << "size:" << mylist.size() << endl;

	cout << mylist.empty() << endl;
	if (mylist.empty())
	{
		cout << "空" << endl;
	}
	else
	{
		cout << "不为空" << endl;
	}

	mylist.resize(3);

	printList(mylist);

}

​ 4.赋值操作
5.数据的存取

/*
赋值操作,数据的存取
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);//将n个elem拷贝赋值给本身。
list&operator=(const list &lst);//重载等号操作符
swap(lst);//将lst与本身的元素互换。

front();//返回第一个元素。
back();//返回最后一个元素。

*/
void test04()
{
	list<int> mylist;
	mylist.assign(10, 10);
	printList(mylist);

	cout << mylist.front() << endl;
	cout << mylist.back() << endl;

	list<int> mylist2;
	for (int i = 0; i < 5; i++)
	{
		mylist2.push_back(i);
	}

	mylist2.swap(mylist);
	printList(mylist2);
}

​ 6.反转和排序

/*
反转 排序
reverse();//反转链表,比如lst包含1,3,5元素,运行此方法后,lst就包含5,3,1元素。
sort(); //list排序

*/

bool myfunc2(int v1, int v2)
{
	return v1 > v2;
}
void test05()
{
	list<int> mylist;
	for (int i = 0; i < 5; i++)
	{
		mylist.push_back(i + 10);
	}

	printList(mylist);

	mylist.reverse();

	printList(mylist);

	//注意:list容器不能使用sort算法
	//sort(mylist.begin(), mylist.end());
	mylist.sort();

	printList(mylist);

	mylist.sort(myfunc2);
	printList(mylist);
}

int main()
{
	test05();
	system("pause");
	return EXIT_SUCCESS;
}

4.注意:list容器不能使用常用的sort,只能使用自己的sort

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<list>

void test()
{
	/*list<int>::iterator it;
	it--;
	it++;*/
	//it + 2;err
	//双向迭代器

	list<int> mylist;
	for (int i = 0; i < 10; i++)
	{
		mylist.push_back(i);
	}

	//2015和2017vs :_Myhead==>_Myhead(),_Mysize==>_Mysize()
	list<int>::_Nodeptr node = mylist._Myhead()->_Next;//头节点的下一个节点

	for (int i = 0; i < mylist._Mysize() * 2; i++)
	{
		cout << "Node:" << node->_Myval << endl;//获取节点数据
		node = node->_Next;
		if (node == mylist._Myhead())
		{
			node = node->_Next;
		}
	}

}

int main()
{
	test();

	system("pause");
	return EXIT_SUCCESS;
}

04.电梯案例(了解)

1.目的:获取进出电梯人数及姓名,并打印出来

2.思路:

​ 1.抽象人员

​ 2.抽象电梯(list)

​ 3.进电梯的人(queue)

​ 4.把进电梯和出电梯的人拷贝一份放入vector中,待打印

3.流程:

​ 1.电梯上升

​ 2.创建人员

​ 3.判断进电梯条件,然后进电梯

​ 4.判断出电梯条件,然后出电梯

​ 5.打印出电梯和进电梯人员的人数和姓名

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<list>
#include<vector>
#include<queue>
#include<string>
#include<ctime>

//抽象人员
class Student
{
public:
	string name;
};

//打印人员
void printVector(vector<Student> &vec)
{
	for (vector<Student>::iterator it = vec.begin(); it != vec.end(); ++it)
	{
		cout << (*it).name << endl;
	}
}

//创建人员
void CreateStudent(queue<Student> &que,int num)
{
	string setName = "ABCDEFGHIJKLMN";
	int sum = rand() % 10;
	for (int i = 0; i < sum; i++)
	{
		Student stu;

		char buf[64] = { 0 };
		sprintf(buf, "%d", num);
		string s(buf);

		stu.name = "第";
		stu.name += s;
		stu.name += "层";
		stu.name += setName[i];

		que.push(stu);//每层的人员放入队列容器
	}
}
//mylist是电梯,que队列容器,pushV是拷贝进电梯的人员
int PushList(list<Student> &mylist,queue<Student> &que,vector<Student> &pushV)
{
	int tmppush = 0;//临时变量,记录出电梯人员数
	
	while (!que.empty())
	{
		if (mylist.size() >= 15)//电梯满了
		{
			break;
		}

		Student s = que.front();

		//拷贝到vector
		pushV.push_back(s);

		//进电梯
		mylist.push_back(s);

		//队列中队头元素出容器
		que.pop();

		tmppush++;
	}

	return tmppush;
}
//mylist是电梯,popV记录出电梯人员,num层数
int PopList(list<Student> &mylist, vector<Student> &popV,int num)
{
	int tmppop = 0;

	if (num == 17)//当到达17层,那么所有的人都要出电梯
	{
		while (!mylist.empty())
		{
			Student s=mylist.front();
			//把出电梯的人员拷贝到popV中
			popV.push_back(s);

			mylist.pop_front();//移除电梯的人
			tmppop++;
		}
	}

	int n = rand() % 5;//随机出电梯人数
	if (n == 0)
	{
		return tmppop;
	}
	//当电梯有人,且人数大于等于随机出电梯的人数才让人出电梯
	if (mylist.size() > 0 && mylist.size() >= n)
	{
		for (int i = 0; i < n; i++)
		{
			Student s = mylist.front();

			//把出电梯的人员拷贝到popV中
			popV.push_back(s);
			mylist.pop_front();//移除电梯的人
			tmppop++;
		}
	}

	return tmppop;
}
void test()
{
	srand((unsigned int)time(NULL));
	list<Student> mylist;//创建电梯

	int Pushnum = 0;//记录进电梯的总人数
	int Popnum = 0;//记录出电梯的总人数

	vector<Student> pushV;//记录进电梯的人员
	vector<Student> popV;//记录出电梯的人员

	//电梯上升
	for (int i = 1; i < 18; i++)
	{
		//创建人员
		queue<Student> que;
		//创建人员函数
		CreateStudent(que, i);

		//判断是否能进电梯
		if (mylist.size() <= 15)
		{
			//17层不要进人,到17层事件结束
			if (i < 17)
			{
				//进电梯
				Pushnum += PushList(mylist, que, pushV);
			}
		}

		//判断出电梯条件
		if (mylist.size()>0)//电梯要有人才能出
		{
			if (i > 1)//1层时,电梯是空的
			{
				//出电梯
				Popnum += PopList(mylist, popV, i);
			}
		}
	}

	//打印进电梯的人员
	printVector(pushV);
	cout << "进电梯人数:" << Pushnum << endl;
	//打印出电梯的人员
	printVector(popV);
	cout << "出电梯人数:" << Popnum << endl;

}

int main()
{
	test();
	system("pause");
	return EXIT_SUCCESS;
}

05.pair对组(了解)

1.pair对组是一个类,类中有两个公有的成员变量

2.对组通常用来接收key-vluae这样的元素

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


int main()
{
	pair<string, int> myp("aaa", 10);

	cout << myp.first << " " << myp.second << endl;

	pair<int, string> myp2(1, "ОтїХ");
	cout << myp2.first << " " << myp2.second << endl;

	//key -->value
	system("pause");
	return EXIT_SUCCESS;
}

06.set/multiset容器(重点难点)

1.set容器是关联式容器,容器自身有规则,通过键值排序,set容器中的元素是键值也是实值

2.set容器和multiset容器的区别是multiset允许有相同的元素

3.数据结构:平衡二叉树

4.迭代器:双向迭代器

5.常用的api:

​ 1.构造
​ 2.赋值
​ 3.大小
​ 4.插入和删除

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<set>//multset也是这个头文件
#include<algorithm>
#include<string>

void test()
{
	set<int>::iterator it;
	it++;
	it--;
	//it + 2;err
	//双向迭代器
}

void printSet(set<int>& s)
{
	for (set<int>::iterator it = s.begin(); it != s.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}
/*
构造函数
set<T> st;//set默认构造函数:
mulitset<T> mst; //multiset默认构造函数:
set(const set &st);//拷贝构造函数

赋值操作
set&operator=(const set &st);//重载等号操作符
swap(st);//交换两个集合容器
大小操作
size();//返回容器中元素的数目
empty();//判断容器是否为空

插入和删除操作
insert(elem);//在容器中插入元素。
clear();//清除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(elem);//删除容器中值为elem的元素。


*/

void test01()
{
	set<int> s;
	s.insert(4);
	s.insert(8);
	s.insert(2);
	s.insert(10);
	s.insert(7);
	//自身规则进行排序,从小到大
	printSet(s);


}

struct myfunc
{
	bool operator()(int v1, int v2)
	{
		return v1 > v2;
	}
};
void printSet2(set<int, myfunc>& s)
{
	for (set<int, myfunc>::iterator it = s.begin(); it != s.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}
//改变set容器的规则,变为降序(从大到小)
void test02()
{
	set<int, myfunc> s;
	s.insert(4);
	s.insert(8);
	s.insert(2);
	s.insert(10);
	s.insert(7);

	printSet2(s);
}


//set容器不允许有两个相同的元素
void test03()
{

	set<int, myfunc> s;
	s.insert(4);
	s.insert(8);
	s.insert(2);
	s.insert(10);
	s.insert(7);

	printSet2(s);
	//注意:set容器不允许有两个相同的元素,但是插入相同的元素,编译不会报错,运算也不报错
	//只是不把数据输入容器
	s.insert(8);
	printSet2(s);

	pair<set<int, myfunc>::iterator, bool> ret = s.insert(11);

	if (ret.second)
	{
		cout << "插入成功" << endl;
	}
	else
	{
		cout << "插入失败" << endl;
	}

	s.erase(2);
	s.erase(s.begin());
	printSet2(s);
}
void print(int v)
{
	cout << v << " ";
}
//不能通过算法排序
void test04()
{
	multiset<int> s;
	s.insert(4);
	s.insert(8);
	s.insert(2);
	s.insert(2);
	s.insert(7);
	//自身规则进行排序,从小到大
	//不能通过算法排序来排序关联式容器的元素
	//sort(s.begin(), s.end());

	for_each(s.begin(), s.end(), print);
	cout << endl;
}

​ 5.查找操作

/*
查找操作
find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
1.	count(key);//查找键key的元素个数
2.	lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
3.	upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。

*/
void test05()
{
	set<int> s;
	s.insert(4);
	s.insert(8);
	s.insert(6);
	s.insert(9);
	s.insert(7);
	set<int>::iterator it = s.find(10);
	if (it == s.end())
	{
		cout << "查找失败" << endl;
	}
	else
	{
		cout << "查找成功:" << *it << endl;
	}
	//查找大于等于2的最小的数
	it = s.lower_bound(2);
	if (it == s.end())
	{
		cout << "查找失败" << endl;
	}
	else
	{
		cout << "查找成功:" << *it << endl;
	}
	//查找大于2的最小的数
	it = s.upper_bound(2);
	if (it == s.end())
	{
		cout << "查找失败" << endl;
	}
	else
	{
		cout << "查找成功:" << *it << endl;
	}
	//返回大于等于2的两个最小的数,如果有2那么就返回2和大于2的最小数
	pair<set<int>::iterator, set<int>::iterator> ret = s.equal_range(2);
	cout << *(ret.first) << endl;
	cout << *(ret.second) << endl;

	multiset<int> s1;
	s1.insert(4);
	s1.insert(4);
	s1.insert(4);
	s1.insert(9);
	s1.insert(7);

	cout << s1.count(4) << endl;
}

//存储对象时,需要告诉set容器规则
class Maker
{
public:
	Maker(string name, int age)
	{
		this->name = name;
		this->age = age;
	}
public:
	string name;
	int age;
};

struct Makerfunc
{
	bool operator()(const Maker& m1, const Maker& m2)
	{
		return m1.age > m2.age;
	}
};
void test06()
{
	set<Maker, Makerfunc> s;
	s.insert(Maker("aaa", 18));
	s.insert(Maker("bbb", 19));
	s.insert(Maker("ccc", 20));
	s.insert(Maker("ddd", 21));
	s.insert(Maker("eee", 22));

	for (set<Maker, Makerfunc>::iterator it = s.begin(); it != s.end(); ++it)
	{
		cout << "Name:" << it->name << " Age:" << it->age << endl;
	}
}
int main()
{
	test06();
	system("pause");
	return EXIT_SUCCESS;
}

6.改变规则:默认是从小到大,改变规则,加入谓词到<>第二个参数中

7.注意:

​ 1.set容器插入相同元素时,不会报错,但是不插入数据

​ 2.set容器存储对象时,需要告诉set容器的规则

07.map/multimap容器(重点难点)

1.map/multimap也是关联式容器,容器自身有规则,通过键值排序,map容器中的元素是对组,对组的第一个元素是键值,不能改变,第二个元素是实值,可以改变

2.数据结构:平衡二叉树

3.迭代器:双向迭代器

4.map容器和multimap容器的区别是multimap允许有相同的元素

5.常用的api:

​ 1.构造
​ 2.赋值
​ 3.大小
​ 4.查找
​ 5.插入
​ 6.删除

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

void test()
{
	map<int, string>::iterator it;
	it--;
	it++;
	//it + 2;双向迭代器
}
/*
插入数据元素操作
map.insert(...); //往容器插入元素,返回pair<iterator,bool>
map<int, string> mapStu;
// 第一种 通过pair的方式插入对象
mapStu.insert(pair<int, string>(3, "小张"));
// 第二种 通过pair的方式插入对象
mapStu.inset(make_pair(-1, "校长"));
// 第三种 通过value_type的方式插入对象
mapStu.insert(map<int, string>::value_type(1, "小李"));
// 第四种 通过数组的方式插入值
mapStu[3] = "小刘";
mapStu[5] = "小王";

*/

template<class T>
void printMap(T& m)
{
	for (map<int, string>::iterator it = m.begin(); it != m.end(); ++it)
	{
		cout << "key:" << it->first << " value:" << it->second << endl;
	}
}

void test01()
{
	map<int, string> mymap;

	//1.
	mymap.insert(pair<int, string>(3, "aaa"));
	//2.
	mymap.insert(make_pair(6, "bbb"));
	//3.
	mymap.insert(map<int, string>::value_type(2, "ccc"));
	//4.
	mymap[4] = "ddd";

	printMap(mymap);

}
//改变规则
struct mapfunc
{
	bool operator()(int key1, int key2)
	{
		return key1 > key2;
	}
};
void test02()
{
	map<int, string, mapfunc> mymap;

	//1.
	mymap.insert(pair<int, string>(3, "aaa"));
	//2.
	mymap.insert(make_pair(6, "bbb"));
	//3.
	mymap.insert(map<int, string>::value_type(2, "ccc"));
	//4.
	mymap[4] = "ddd";

	printMap(mymap);

}

//注意:[]方式插入数据,如果没有实值,那么键值也是存在的
void test03()
{
	map<int, string> mymap;

	//1.
	mymap.insert(pair<int, string>(3, "aaa"));
	//2.
	mymap.insert(make_pair(6, "bbb"));
	//3.
	mymap.insert(map<int, string>::value_type(2, "ccc"));
	//4.
	mymap[4] = "ddd";

	printMap(mymap);

	cout << "size:" << mymap.size() << endl;

	cout << mymap[100] << endl;//插入键值,返回的是实值
	cout << "size:" << mymap.size() << endl;
}
/*
查找
find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;/若不存在,返回map.end();
count(keyElem);//返回容器中key为keyElem的对组个数。对map来说,要么是0,要么是1。对multimap来说,值可能大于1。
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。

*/
void test04()
{
	map<int, string> mymap;
	mymap[1] = "aaa";
	mymap[2] = "bbb";
	mymap[3] = "ccc";
	mymap[4] = "ddd";
	mymap[5] = "eee";

	map<int, string>::iterator it = mymap.find(30);
	if (it == mymap.end())
	{
		cout << "查找失败" << endl;
	}
	else
	{
		cout << "key:" << it->first << " value:" << it->second << endl;
	}
	//查找大于等于3的最小的数
	it = mymap.lower_bound(3);
	if (it == mymap.end())
	{
		cout << "查找失败" << endl;
	}
	else
	{
		cout << "key:" << it->first << " value:" << it->second << endl;
	}
	//查找大于3的最小的数
	it = mymap.upper_bound(3);
	if (it == mymap.end())
	{
		cout << "查找失败" << endl;
	}
	else
	{
		cout << "key:" << it->first << " value:" << it->second << endl;
	}
	cout << "--------------" << endl;
	//返回大于等于2的两个最小的数,如果有2那么就返回2和大于2的最小数
	pair<map<int, string>::iterator, map<int, string>::iterator> ret = mymap.equal_range(3);

	if (ret.first != mymap.end())
	{
		cout << "key:" << ret.first->first << " Value:" << ret.first->second << endl;
	}

	if (ret.second != mymap.end())
	{
		cout << "key:" << ret.second->first << " Value:" << ret.second->second << endl;

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

08.案例(重点)

1.目的:公司今天招聘了5个员工,5名员工进入公司之后,需要指派员工在那个部门工作,指派完成后打印员工部门和员工信息

2.思路:

​ 1.抽象员工

​ 2.把未分组员工放入到vector容器中

​ 3.把分组好的员工信息放入到multimap中

3.流程:

​ 1.创建员工

​ 2.分组员工

​ 3.打印员工信息

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

#define SALE_DEPATMENT 1 //销售部门
#define DEVELOP_DEPATMENT 2 //研发部门
#define FINACIAL_DEPATMENT 3 //财务部门

class Woker
{
public:
	string name;//姓名
	int age;//年龄
	int Salary;//薪资
};

//创建员工
void CreateWoker(vector<Woker> &vWoker)
{
	srand((unsigned int)time(NULL));

	string setName = "ABCDE";
	for (int i = 0; i < 5; i++)
	{
		Woker woker;
		woker.name = "员工";
		woker.name += setName[i];
		woker.age = rand() % 30 + 30;
		woker.Salary = rand() % 20000 + 20000;
		vWoker.push_back(woker);
	}

}
//分组,把分好组的员工放入mWokers
void WokerByGroup(vector<Woker> &vWoker, multimap<int,Woker> &mWokers)
{
	//遍历员工
	for (vector<Woker>::iterator it = vWoker.begin(); it != vWoker.end(); ++it)
	{
		//生成部门编号
		int id = rand() % 3 + 1;
		//员工保存到mWokers
		mWokers.insert(make_pair(id, *it));
	}
}
void myGroup(multimap<int, Woker> &mWokers, int id)
{
	//查询id
	multimap<int, Woker>::iterator it = mWokers.find(id);
	//查询部门人数
	int mcount = mWokers.count(id);

	//临时变量
	int index = 0;
	for (; it != mWokers.end() && index<mcount; ++it,++index)
	{
		cout << "Name:" << it->second.name << " Age:" << it->second.age << " Salary:" << it->second.Salary << endl;
	}

}
//打印员工信息
void PrintWoker(multimap<int, Woker> &mWokers)
{

	cout << "财务部门员工信息如下:" << endl;
	myGroup(mWokers, FINACIAL_DEPATMENT);

	cout << "研发部门员工信息如下:" << endl;
	myGroup(mWokers, DEVELOP_DEPATMENT);

	cout << "销售部门员工信息如下:" << endl;
	myGroup(mWokers, SALE_DEPATMENT);

}

void test()
{
	//保存未分组的员工信息
	vector<Woker> vWoker;
	//保存分组后员工的信息
	multimap<int, Woker> mWokers;

	//创建员工
	CreateWoker(vWoker);
	//分组,把分好组的员工放入mWokers
	WokerByGroup(vWoker, mWokers);
	//打印员工信息
	PrintWoker(mWokers);
}

int main()
{
	test();
	
	system("pause");
	return EXIT_SUCCESS;
}

09.STL的深浅拷贝问题(了解)

1.把对象放入容器,其实是拷贝一份对象到容器。

2.注意:

​ 1.拷贝构造要能被调用
​ 2.注意要浅拷贝问题

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

class Maker
{
public:
	Maker(int age)
	{
		this->age = age;
	}
	Maker(const Maker& m)
	{
		cout << "拷贝构造" << endl;
	}
public:
	int age;
};

void test()
{
	vector<Maker> v;
	Maker m(10);
	//1.拷贝构造要能被调用
	//2.注意要浅拷贝问题
	v.push_back(m);
}

int main()
{
	test();
	system("pause");
	return EXIT_SUCCESS;
}

10.函数对象(重点)

1.什么是函数对象

​ 1.类中重载了(),这个类实例化的对象叫函数对象(仿函数);

​ 2.一元仿函数是operator()中只需要一个参数。二元仿函数是operator()中需要二个参数

2.有什么用

​ 1.做为算法的策略

void test()
{
	vector<int> v;
	v.push_back(8);
	v.push_back(1);
	v.push_back(6);
	v.push_back(3);
	v.push_back(7);


	sort(v.begin(), v.end(), greater<int>());

	for_each(v.begin(), v.end(), [](int val){cout << val << " "; });
	//[](int val){cout << val << " "; }//匿名函数


}

3.函数对象和普通函数的区别

​ 1.函数对象可以有自己的状态

​ 2.普通函数没有类型,函数对象有类型

​ 3.函数对象比普通函数执行效率有可能更高(成员函数自动申请为内联函数)

4.谓词

​ 1.谓词是指普通函数或重载的operator()返回值是bool类型的函数对象(仿函数)。

​ 2.谓词可以作为一个判断式

​ 3.接受一个参数,那么叫做一元谓词,如果接受两个参数,那么叫做二元谓词

5.内建函数对象

​ 1.使用内建的函数对象要加入头文件#include

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

void test()
{
	vector<int> v;
	v.push_back(8);
	v.push_back(1);
	v.push_back(6);
	v.push_back(3);
	v.push_back(7);


	sort(v.begin(), v.end(), greater<int>());

	for_each(v.begin(), v.end(), [](int val){cout << val << " "; });
	//[](int val){cout << val << " "; }//匿名函数


}

void func()
{

}

struct Myfunc//函数对象有类型
{
public:
	Myfunc()
	{
		n = 0;
	}
	void operator()()//函数对象有自己的状态
	{
		cout << "hello" << endl;
	}
public:
	int n;

};

void test01()
{
	plus<int> myplus;
	cout << myplus(10, 20) << endl;


}

int main()
{
	

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值