STL常用容器_2

news2025/1/13 15:34:16

目录

一、stcak容器(栈容器)

1、基本概念

 2、常用接口

二、queue容器(队列容器)

1、基本概念

2、常用接口函数

三、list容器(链表)

1、基本概念

2、构造函数

3、赋值与交换

4、大小操作

5、插入与删除

6、数据存取

7、反转和排序

8、排序的案例

四、set/multiset容器

1、基本概念

2、构造函数

3、大小与交换操作

4、插入和删除操作

5、查找和统计操作

6、set/multiset区别

7、pair对组创建

8、排序

五、map/multimap容器

1、基本概念

2、构造函数与赋值

3、大小和交换操作

4、插入和删除操作

5、查找和统计操作

6、排序

六、案例-员工分组

具体实现:


一、stcak容器(栈容器)

1、基本概念

只有一个出口,FILO(First In Last Out),数据先进后出

 2、常用接口

/*
1、构造函数
stack<T> stk;	stack采用模板类实现,stack对象的默认构造
stack(const stack& stk);	拷贝构造
2、赋值操作
stack& operator=(const stack & stk);  重载=运算符
3、数据存取
stk.push(elem);		向栈顶添加元素
stk.pop();			删除栈顶元素
stk.top();			返回栈顶元素
4、大小操作
stk.empty();		判断堆栈是否为空
stk.size();			返回栈的大小
*/

测试:

void test01()
{
	stack<int> s; // 创建栈容器s
	s.push(1);
	s.push(2);// 插入元素
	s.push(3);
	s.push(4);
	cout << s.size() << endl; // 查看大小
	cout << s.empty() << endl;// 判断是否为空,不为空返回0
	while (!s.empty()) // 不为空执行循环
	{
		cout << s.top(); // 输出栈顶元素
		s.pop(); // 出栈
	}
	cout << endl;
	cout << s.size() << endl; // 查看大小
	cout << s.empty() << endl;// 判断是否为空,为空返回1
}


二、queue容器(队列容器)

1、基本概念

有两个出口,FIFO(First In First Out),数据先进先出

2、常用接口函数

/* queue容器
1、构造函数
queue<T> que;	queue采用模板类实现,queue对象的默认构造
queue(const queue& que);	拷贝构造
2、赋值操作
queue& operator=(const queue & que);  重载=运算符
3、数据存取
que.push(elem);		向队尾添加元素
que.pop();			删除队头元素
que.front();		返回队头元素
que.back();			返回队尾元素
4、大小操作
que.empty();		判断堆栈是否为空
que.size();			返回队列的大小
*/

测试:

这里我使用自定义数据类型person

class person
{
public:
	person(string name,int age)
	{
		this->m_name = name;
		this->m_age = age;
	}
	string m_name;
	int m_age;
};
void test02()
{
	queue<person> q;// 创建queue容器q
	// 先创建几个person类型对象
	person p1("Joyce", 21);
	person p2("Tatina", 20);
	person p3("Yomi", 2);
	person p4("Nna", 15);
	// 插入到容器q中 入队
	q.push(p1);
	q.push(p2);
	q.push(p3);
	q.push(p4);
	// 打印p中的数据
	cout << q.size() << endl; // 查看大小
	cout << q.empty() << endl;// 判断是否为空,不为空返回0
	while (!q.empty()) // 不为空执行循环
	{
		cout << "头"<<q.front().m_name << q.front().m_age << endl; // 输出队头元素
		cout << "尾" << q.back().m_name << q.back().m_age << endl; // 输出队尾元素
		q.pop(); // 删除队头元素
	}
	cout << q.size() << endl; // 查看大小
	cout << q.empty() << endl;// 判断是否为空,为空返回1
}


三、list容器(链表)

1、基本概念

概念:list是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针域链接实现的

功能:将数据进行链式存储

组成:链表由一系列结点组成,

结点:由存储数据的数据域和存储下一个结点地址的指针域组成

与指针的区别:

 STL中的list是一个双向循环链表

 任意一个结点都有着数据域与包含2个指针的指针域,1个指针是prev指向前一个结点的地址,另1个指针是next指向下一个结点的地址

同时含有很多迭代器:push_front()、push_back()、pop_front()、pop_back()等

由于链表的存储方式不是连续的内存空间,因此链表中的迭代器只支持前移--和后移++,不可以+*好几个数,属于双向迭代器

链表优点:

①采用动态内存分配,不会造成内存浪费与溢出

②链表插入与删除操作非常方便,修改指针即可,不需要移动大量元素

缺点:

灵活但空间(指针域)和时间(遍历)额外耗费大


链表的重要性质:插入和删除操作都不会造成原有迭代器的失效,而在vector,插入删除会开辟新的内存,使原有迭代器指向错误的空间


2、构造函数

功能:创建list容器

/*构造函数
list<T> lst;		1使用模板类实现,默认构造
list(begin,end);	2将区间[begin,end)中的元素拷贝给自身,注意区间左闭右开
list(n,elem);		3将n个elem元素拷贝给自身
list(const list& lst); 4将lst拷贝给自身,拷贝构造函数
*/

测试:

void test03()
{
	list<int> l1;// 1创建容器
	l1.push_back(1);// 插入元素
	l1.push_back(2);
	l1.push_back(3);
	l1.push_back(4);
	printl(l1); // 打印函数

	list<int> l2(l1.begin(), l1.end()); // 2
	printl(l2);

	list<int> l3(5, 888); // 3
	printl(l3);

	list<int> l4(l1); // 4
	printl(l4);
}

其中,我实现了一个打印函数(下面所有打印数据都用这个函数,每一行数据代表一次调用)

void printl(const list<int>& l) // 打印函数
{
	for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

和vector容器创建容器方法基本相同


3、赋值与交换

功能:给list容器赋值,以及交换list容器

/*赋值与交换
list operator=(const list& lst);  重载=运算符
lst.assign(begin,end);			将区间[begin,end)中的数据拷贝给自身,注意区间左闭右开
lst.assign(n,elem);				将n个elem元素拷贝给自身
lst.swap(lst1);					将lst1的元素与自身交换
*/


4、大小操作

功能:对list容器的大小进行操作

/*容量和大小
lst.empty();			 1判断容器是否为空,空返回true1否则false0
lst.size();		   		 2返回容器当前大小
lst.resize(int n);		3重新指定容器长度为n,若容器变长,则以默认值0填充新位置。
										  若容器变短,则末尾超出容器长度的元素被删除
lst.resize(int n,elem); 4重新指定容器长度为n,若容器变长,则以elem填充新位置。
										  若容器变短,则末尾超出容器长度的元素被删除
*/


5、插入与删除

功能:对容器中元素进行插入与删除操作

/*插入与删除
lst.push_front(elem);			 1头部插入elem元素
lst.pop_front();				 2删除头部第一个元素
lst.push_back(elem);			 3尾部插入elem元素
lst.pop_back();					 4删除尾部最后一个元素
lst.insert(const_iterator pos,elem);		5在迭代器指向的pos位置插入元素elem
lst.insert(const_iterator pos,int n,elem);	6在迭代器指向的pos位置插入n个elem元素
lst.insert(const_iterator pos,const_iterator start,const_iterator end); 
				7在迭代器指向的pos位置插入从start到end区间的元素
lst.erase(const_iterator pos);	 8删除迭代器指向的pos位置的元素
lst.erase(const_iterator start,const_iterator end); 9删除迭代器指向的从start到end区间的元素
lst.clear();					 10删除容器中所有元素
lst.remove(elem);					11删除容器中所有与elem值匹配的元素
*/

 测试:

void test06()
{
	list<int> l1;// 创建容器
	l1.push_back(1);//    3尾插 
	l1.push_back(2);
	l1.push_back(3);
	l1.push_back(4);
	printl(l1);
	l1.push_front(40); // 1头插
	l1.push_front(30);
	l1.push_front(20);
	l1.push_front(10);
	printl(l1);

	l1.pop_back();	   // 4尾删
	l1.pop_back();
	printl(l1);
	l1.pop_front();	   // 2头删
	l1.pop_front();
	printl(l1);

	l1.insert(l1.begin(), 888); // 5 插入指定元素
	printl(l1);

	l1.insert(l1.begin(), 8, 66); // 6 插入指定个数元素
	printl(l1);

	l1.insert(l1.begin(),l1.begin(),l1.end()); // 7 头部插入区间元素
	printl(l1);

	l1.erase(l1.begin()); // 8 删除指定位置元素
	printl(l1);

	list<int> l2 = l1;
	printl(l2);
	l2.erase(++l2.begin(), --l2.end()); // 9 删除指定区间元素
	printl(l2);

	l1.remove(66); // 11 删除容器中指定的所有元素
	printl(l1);

	l1.clear();
	printl(l1);		// 10 清空容器
}

一行数据对应一个printl,上面挡住了第一个prinl 


6、数据存取

功能:对list中容器进行存取操作

/*数据存取
lst.front();	返回队头元素
lst.back();		返回队尾元素
*/

测试:

首先:

void test07()
{
	list<int> l1;// 创建容器
	l1.push_back(1);//    3尾插 
	l1.push_back(2);
	l1.push_back(3);
	l1.push_back(4);
	printl(l1);

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

	cout << ++l1.front() << endl; // 只能前移或后移
	cout << l1.back()-- << endl;
}

7、反转和排序

功能:将容器中的元素进行反转与排序

/*反转与排序
lst.reverse();	反转链表
lst.sort();		排序链表
*/

测试:

void test08()
{
	list<int> l1;// 创建容器
	l1.push_back(1);//    3尾插 
	l1.push_back(9);
	l1.push_back(8);
	l1.push_back(7);
	printl(l1);

	l1.reverse(); // 反转
	printl(l1);

	l1.sort();	  // 排序
	printl(l1);
}

注意:所有不支持随机访问迭代器的容器,不可以用标准算法<algorithm>,而容器内部会提供一些对应的算法 

而list容器内sort默认是升序,如果想要降序,我们需要重载sort:

首先自己实现仿函数

bool my_compare(int x, int y)
{
	return x > y;
}

调用sort重载

	l1.sort(my_compare); // 降序
	printl(l1);


8、排序的案例

描述:创建自定义类型person,内有属性姓名、年龄、身高

排序:按照年龄升序排列,如果年龄相同,按身高升序排列

void test09()
{
	list<person> l; // 创建容器
	// 根据自定义数据类型创建对象
	person p1("Joyce", 21, 180);
	person p2("Tatina", 20, 162);
	person p3("Yomi", 2, 30);
	person p4("Nana", 20, 180);
	// 插入进容器
	l.push_back(p1);
	l.push_back(p2);
	l.push_back(p3);
	l.push_back(p4);
	printp(l); // 打印查看
	l.sort(my_compare);
	printp(l); // 打印查看
}

打印函数printp

void printp(const list<person>&p)
{
	for (list<person>::const_iterator it = p.begin(); it != p.end(); it++)
	{
		cout << "姓名" << (*it).m_name << "年龄" << (*it).m_age << "身高" << (*it).m_height << endl;
	}
	cout << endl;
}

 排序函数sort();我们加上仿函数 使其重载(指定排序规则)

bool my_compare(person &p1,person& p2) // 仿函数
{
	if (p1.m_age == p2.m_age) // 年龄相同
	{
		return p1.m_height < p2.m_height;// 按照身高升序
	}
	else
	{
		return p1.m_age < p2.m_age;// 按照年龄升序
	}
}

 

成功以年龄和身高排序 

 以上就是list容器的所有内容


四、set/multiset容器

1、基本概念

特点:所有元素在插入时会被自动排序

本质:set/multiset属于关联式容器,底层结构是用二叉树实现

二者区别:

①set容器不允许有重复的元素

②multiset容器允许有重复的元素


ps:在所有代码之前,我先实现一个打印函数,以便后面打印输出容器中的数据

void prints(set<int> st)
{
	for (set<int>::iterator it = st.begin(); it != st.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

2、构造函数

作用:创建set容器及赋值

/*构造函数
set<T> st;			1默认构造函数
set(const set &st); 2拷贝构造函数
set& operator=(const set& st);  3重载=运算符
*/

测试:

void test01()
{
	set<int> st1;  // 1
	st1.insert(1);
	st1.insert(8);
	st1.insert(6);
	st1.insert(3);
	st1.insert(8); // 重复的8,无法插入
	prints(st1);

	set<int>st2(st1); // 2
	prints(st2);

	set<int>st3;
	st3 = st1; // 3
	prints(st3);
}

 可见,set容器无法插入相同元素


3、大小与交换操作

作用:统计set容器大小,以及交换set容器

首先,由于set容器不允许有重复的元素,因此它没有指定容器大小的函数

/*大小与交换
st.size();		返回容器中元素的个数
st.empty();		判断容器是否为空,空返回1,否则返回0
st.swap(st1);	交换2个容器
*/

测试:

void test02()
{
	set<int> st1;  
	cout << st1.size() << endl;
	cout << st1.empty() << endl;
	st1.insert(1);
	st1.insert(8);
	st1.insert(6);
	st1.insert(3);
	cout << st1.size() << endl;
	cout << st1.empty() << endl;

	set<int> st2;
	st2.insert(88);	st2.insert(66);
	st2.insert(54);	st2.insert(13);
	cout << "交换前" << endl;
	prints(st1);
	prints(st2);
	st2.swap(st1);
	cout << "交换后" << endl;
	prints(st1);
	prints(st2);
}


4、插入和删除操作

作用:对set容器中元素进行插入和删除操作

/*插入和删除
st.insert();		1插入元素
st.clear();			2清空容器
st.erase(pos);		3删除迭代器pos处的元素
st.erase(begin,end);4删除迭代器区间begin,end之间的元素
st.erase(elem);		5删除elem元素
*/

测试:

void test03()
{
	set<int> st1;
	st1.insert(1);	// 1
	st1.insert(8);
	st1.insert(6);
	st1.insert(3);
	st1.insert(5);
	st1.insert(9);
	prints(st1);

	st1.erase(++st1.begin());// 3
	prints(st1);
	st1.erase(++st1.begin(), --st1.end());// 4
	prints(st1);
	st1.erase(1);
	prints(st1);		// 5
	st1.clear();		// 2
	prints(st1);	
}


5、查找和统计操作

作用:对set容器进行查找数据以及统计数据

/* 查找与统计
st.find(val);	查找val元素是否存在,存在返回其位置的迭代器,否则返回st.end();
st.count(val);	统计元素val的个数
*/

由于set容器中没有重复元素,因此count只有0/1

测试:

void test04()
{
	set<int> st1;
	st1.insert(1);	
	st1.insert(8);
	st1.insert(6);
	st1.insert(3);

	set<int> ::iterator pos = st1.find(3);
	if (pos == st1.end())
		cout << "没找到" << endl;
	else
		cout << "有了" << endl;
	cout << st1.count(3) << endl;
}


6、set/multiset区别

区别:

①set不可以重复插入,multiset可以

②set插入数据的同时会返回插入结果,表示是否成功

③multiset不会检测数据,因此可以重复插入相同元素


因为set的insert是对组pair,有两个数据:iterator代表返回的位置,bool代表是否插入成功

 我们创建容器,尝试插入1个与2个相同数据,并通过返回值的第二个数据bool值判断是否成功

void test05()
{
	set<int> s;

	pair<set<int>::iterator,bool> ret = s.insert(5);
	if (ret.second)
		cout << "插入成功" << endl;
	else
		cout << "插入失败" << endl;
	ret = s.insert(5);
	if (ret.second)
		cout << "插入成功" << endl;
	else
		cout << "插入失败" << endl;

}

由此可见,第一次成功,第二次失败。

而相对的,multiset的insert就只有一个iterator代表插入后返回的位置

 因此,它可以重复插入相同元素

multiset<int>ms;
	ms.insert(5);
	ms.insert(5);
	ms.insert(5);
	ms.insert(5);
	for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++)
		cout << *it << " ";


7、pair对组创建

对组:成对出现的数据,利用对组可以返回2个数据

/*对组的创建
pair<type,type> p(val1,val2);
pair<type,type> p=make_pair(val1,val2);
*/

 测试:

void test06()
{
	pair<string, int>p1("Joyce", 21);
	cout << p1.first <<"年"<< p1.second << endl;

	pair<string, int>p2 = make_pair("Tatina", 20);
	cout << p2.first << "年" << p2.second << endl;
}

使用p.first/p.second来访问对组


8、排序

作用:set容器默认排序为升序,我们使用仿函数使其成为降序排列

注意:应在插入数据前就指定其排序规则,否则都插入了无法排序

①内置数据类型排序

void test07()
{
	set<int> st1;
	st1.insert(1);	st1.insert(8);	st1.insert(6);
	st1.insert(3); st1.insert(5); st1.insert(9);
	prints(st1);

	// 进行降序排列
	set<int,MYcompare> st2;
	st2.insert(1);	st2.insert(8);	st2.insert(6);
	st2.insert(3); st2.insert(5); st2.insert(9);
	for (set<int,MYcompare>::iterator it = st2.begin(); it != st2.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

加上仿函数

class MYcompare
{
public:
	bool operator()(int x, int y)const
	{
		return x > y;
	}
};

②自定义数据类型 

对于自定义数据类型,容器中没有可以直接排序的算法,因此我们需要在插入数据前就指定排序规则

自定义数据类型person

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

仿函数

class mycompareperson
{
public:
	bool operator()(const person &p1, const person &p2)const
	{		 // 升序
		return p1.m_age < p2.m_age;
	}
};

测试:

void test08()
{
	set<person, mycompareperson> s1;
	person p1("Joyce", 21);
	person p2("Tatina", 20);
	person p3("Naba", 30);
	person p4("Knaz", 40);
	s1.insert(p1);	s1.insert(p2);
	s1.insert(p3);	s1.insert(p4);
	for (set<person>::iterator it = s1.begin(); it != s1.end(); it++)
		cout << it->m_name << "年龄为" << it->m_age << endl;
}
int ma

 已经按照年龄升序排列

以上就是set/multiset容器 的全部内容


五、map/multimap容器

1、基本概念

简介:

①map中所有元素都是pair

②pair中第一个数据是key(键值,起到索引作用),第二个数据是val(实际存储的值)

③所有元素都会根据元素的键值自动排序

本质:map/multimap属于关联式容器,底层结构是用二叉树实现

优点:可以根据key值快速找到val值

二者区别:

①map不允许有重复key值存在,但可以有重复val值

②multimap允许有重复key值


首先,我先实现一个打印函数,以便下面容器中数据的打印查看,对组中两个数据均为int

 

void printm(map<int, int> mp)
{
	for (map<int, int>::iterator it = mp.begin(); it != mp.end(); it++)
	{
		cout << it->second << " ";
	}
	cout << endl;
}

2、构造函数与赋值

作用:对map容器进行构造与赋值操作

/*构造与赋值
map<T1,T2> mp;				  默认构造函数
map(const map& mp);			  拷贝构造函数
map& operator=(const map &mp);重载=运算符
*/

测试:

void test01()
{
	map<int, int> mp1; // 1
	mp1.insert(pair<int, int>(1, 11));
	mp1.insert(pair<int, int>(2, 22));
	mp1.insert(pair<int, int>(4, 44));
	mp1.insert(pair<int, int>(3, 33));
	printm(mp1);

	map<int, int> mp2(mp1); // 2
	printm(mp2);

	map<int, int> mp3 = mp1; // 3
	printm(mp3);
}


3、大小和交换操作

作用:统计map容器大小,以及交换map容器

首先,由于map容器不允许有重复的元素,因此它没有指定容器大小的函数

/*大小与交换
mp.size();		返回容器中元素的个数
mp.empty();		判断容器是否为空,空返回1,否则返回0
mp.swap(mp1);	交换2个容器
*/

测试:

void test02()
{
	map<int, int> mp1; // 1
	mp1.insert(pair<int, int>(1, 11));	mp1.insert(pair<int, int>(2, 22));
	mp1.insert(pair<int, int>(4, 44));	mp1.insert(pair<int, int>(3, 33));
	cout << mp1.size() << endl;
	cout << mp1.empty() << endl;

	map<int, int> mp2; // 1
	mp2.insert(pair<int, int>(1, 66));	mp2.insert(pair<int, int>(4, 99));
	mp2.insert(pair<int, int>(2, 77));	mp2.insert(pair<int, int>(3, 88));
	cout << "交换前" << endl;
	printm(mp1); printm(mp2);
	mp2.swap(mp1);
	cout << "交换后" << endl;
	printm(mp1); printm(mp2);
}


4、插入和删除操作

作用:对map容器中元素进行插入和删除操作

/*插入和删除
mp.insert();		1插入元素
mp.clear();			2清空容器
mp.erase(pos);		3删除迭代器pos处的元素
mp.erase(begin,end);4删除迭代器区间begin,end之间的元素
mp.erase(val);		5删除容器中key值为val的元素
*/

测试:

void test03()
{
	// insert又有4种方式:
	map<int, int> m;
	m.insert(pair<int, int>(1, 10));// 1.1
	m.insert(make_pair(2, 20));		// 1.2
	m.insert(map<int, int>::value_type(3, 30));// 1.3
	m[4] = 40;	// 1.4
	printm(m);

	m.erase(m.begin()); // 3
	printm(m);

	m.erase(3);  // 5
	printm(m);

	//m.erase(m.begin(), m.end()); // 4 相当于清空
	m.clear(); // 2
	printm(m);

}

 ps:insert又有 4种方式,其中使用[]访问元素的方法不建议拿来插入元素,因为当我们访问到不存在的key时,它会自动生成一个val为0的元素

 因此,一般情况下,[]只用来访问确定已经存在的key值的元素


5、查找和统计操作

作用:对map容器进行查找数据以及统计数据

/* 查找与统计
mp.find(key);	查找key元素是否存在,存在返回其位置的迭代器,否则返回mp.end();
mp.count(key);	统计元素key的个数
*/

由于map容器中没有重复元素,因此count只有0/1

测试:

void test04()
{
	map<int, int> mp1;
	mp1.insert(pair<int, int>(1, 11));	mp1.insert(pair<int, int>(2, 22));
	mp1.insert(pair<int, int>(4, 44));	mp1.insert(pair<int, int>(3, 33));

	map<int,int>::iterator pos = mp1.find(3);
	if (pos != mp1.end())
		cout << "有了:" << (*pos).first << pos->second << endl;
	else
		cout << "没有" << endl;

	cout << mp1.count(3) << endl;
}


6、排序

 作用:map容器默认排序为升序,我们使用仿函数使其成为降序排列

注意:应在插入数据前就指定其排序规则,否则都插入了无法排序

①内置数据类型排序

void test05()
{
	map<int,int> m1;
	m1.insert(pair<int, int>(1, 11));	m1.insert(pair<int, int>(2, 22));
	m1.insert(pair<int, int>(4, 44));	m1.insert(pair<int, int>(3, 33));
	printm(m1);

	// 进行降序排列
	map<int, int, MYcompare> m2;
	m2.insert(pair<int, int>(1, 11));	m2.insert(pair<int, int>(2, 22));
	m2.insert(pair<int, int>(4, 44));	m2.insert(pair<int, int>(3, 33));

	for (map<int, int, MYcompare>::iterator it = m2.begin(); it != m2.end(); it++)
	{
		cout << it->second << " ";
	}
	cout << endl;
}

加上仿函数

class MYcompare
{
public:
	bool operator()(int x, int y)const
	{
		return x > y;
	}
};

以上就是map容器的所有内容


六、案例-员工分组

描述:现招聘10个新员工(ABCDEFGHIJ),进入公司后,需要指派员工到哪个部门工作。

员工信息:姓名+工资。部门:策划+美术+研发

随机给10名员工分配部门与工资

使用multimap进行信息的插入:使用对组(key - 部门编号,val - 员工)

分部门展示员工信息


具体实现:

①创建10名员工,存放至vector容器中

	// 创建员工
	vector<Worker> v;
	createworker(v);

员工信息Worker

class Worker
{
public:
	string m_name;
	int m_salary;
};

创建员工createWorker()

void createworker(vector<Worker>& v)
{
	string nameSeed = "ABCDEFGHIJ";
	for (int i = 0; i < 10; i++)
	{
		Worker worker; // 创建一名员工
		worker.m_name = "员工";
		worker.m_name += nameSeed[i];// 创建员工名字+随机数
		worker.m_salary = 10000 + rand() % 10000;//创建员工工资,10000-19999
		v.push_back(worker);//将员工插入到vector容器中
	}
}

②对员工进行随机分组

	// 员工分组
	multimap<int, Worker> m;
	setDept(v,m);

随机分配部门setDept()

void setDept(vector<Worker> &v, multimap<int, Worker>&m)
{
	// 遍历v的每个元素找到每个员工
	for (vector<Worker>::iterator it = v.begin(); it != v.end(); it++)
	{
		int DeptID = rand() % 3; // 随机分配部门0、1、2
		m.insert(make_pair(DeptID, *it));
	}
}

③查看员工

	// 查看员工
	showWorker(m);

查看员工showWorker()

有2种方法,1种是直接遍历mutilmap容器,如果key值符合部门对应的012,则输出对应val的员工信息

2种是使用multimap的find与count函数来找到对应部门的员工

void showWorker(multimap<int, Worker> m)
{
	cout << "策划部门有:" << endl;
	for (multimap<int, Worker>::iterator it = m.begin(); it != m.end(); it++)
	{
		if (it->first == 0)
		{
			cout << "员工名为:" << it->second.m_name <<
				"工资为:" << it->second.m_salary << endl;
		}
	}
	cout << "美术部门有:" << endl;
	for (multimap<int, Worker>::iterator it = m.begin(); it != m.end(); it++)
	{
		if (it->first == 1)
		{
			cout << "员工名为:" << it->second.m_name <<
				"工资为:" << it->second.m_salary << endl;
		}
	}
	cout << "研发部门有:" << endl;
	for (multimap<int, Worker>::iterator it = m.begin(); it != m.end(); it++)
	{
		if (it->first == 2)
		{
			cout << "员工名为:" << it->second.m_name <<
				"工资为:" << it->second.m_salary << endl;
		}
	}
	//----------------------------------------------------------------------------
	cout << "策划部门有:" << endl;
	multimap<int, Worker>::iterator pos = m.find(CEHUA);
	int count = m.count(CEHUA);
	int index = 0;
	for (pos; pos != m.end() && index < count; pos++, index++)
	{
		cout << "员工名为:" << pos->second.m_name <<
			"工资为:" << pos->second.m_salary << endl;
	}
	cout << "美术部门有:" << endl;
	pos = m.find(MEISHU);
	count = m.count(MEISHU);
	index = 0;
	for (pos; pos != m.end() && index < count; pos++, index++)
	{
		cout << "员工名为:" << pos->second.m_name <<
			"工资为:" << pos->second.m_salary << endl;
	}
	cout << "研发部门有:" << endl;
	pos = m.find(YANFA);
	count = m.count(YANFA);
	index = 0;
	for (pos; pos != m.end() && index < count; pos++, index++)
	{
		cout << "员工名为:" << pos->second.m_name <<
			"工资为:" << pos->second.m_salary << endl;
	}
}

最后加上随机数种子

	srand((unsigned int)time(NULL));

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

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

相关文章

网络层和数据链路层

目录 网络层 IP协议 基本概念 协议头格式 ​编辑 网段划分 特殊的IP地址 IP地址的数量限制 私有IP地址和公网IP地址 路由 ​编辑数据链路层 以太网 以太网帧格式 认识MAC地址 对比理解MAC地址和IP地址 认识MTU MTU对IP协议的影响 ​编辑 MTU对UDP协议的影响 …

新产品上线前需要准备哪些产品文档呢

新产品上线前需要准备的产品文档非常重要&#xff0c;不仅有助于产品的开发过程中沟通和协作&#xff0c;而且对于后期的维护和升级也起到十分重要的作用。下面详细介绍新产品上线前需要准备哪些产品文档。 一、市场需求文档 市场需求文档&#xff08;Market Requirement Doc…

保姆级JAVA对接ChatGPT教程 使用 openai-gpt3-java

1. 前言 必须要有chatGTP 账号&#xff0c;如果需要测试账号可以关注公众号 疯狂的野猿 如果有chatGTP 账号就直接往下看。还需要一台外网服务器使用 nginx 代理来访问chatGTP 如果都没有&#xff0c;可以关注公众号联系作者。 还有笔者已经对接完成了&#xff0c;需要源码的关…

(电脑硬件)台式机主板音频端口功能详解

当你想给你的主机插上音响或者耳机时&#xff0c;你会发现主板上有6个接口&#xff0c;同样都是3.5mm接口&#xff0c;你知道该插哪个吗&#xff1f; 一般情况下&#xff0c;后置输入输出端口面板中&#xff0c;大多数的主板音频部分是彩色的。这一类颜色跟功能基本是固定的。当…

竟然支持在流程图、架构图中添加数学公式,安利一款纯免费的画图工具,真不错!

1. 简介 考虑到在绘图中需要添加数学表达式的场景&#xff0c;PDDON提供了LaTeX表达式编辑能力&#xff0c;可以在任何可以编辑的组件上启用LaTeX功能&#xff0c;使用LaTeX语法编写数学公式即可。 LaTeX表达式简介&#xff1a; LaTeX&#xff08;LATEX&#xff0c;音译“拉泰赫…

【偏门技巧】C语言编程实现对IPV4地址的合法性判断(使用正则表达式)

C语言编程实现对IPV4地址的合法性判断&#xff08;使用正则表达式&#xff09; 有了解过我的朋友&#xff0c;可能有点印象&#xff0c;我在N年前的博客中&#xff0c;就写了这个主题&#xff0c;当时确实是工作中遇到了这个问题。本想着等工作搞完之后&#xff0c;就把这个问题…

C++小知识点(for,nullptr)

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…

Ubuntu用户与用户组相关操作

目录 一、用户与用户组信息查看 二、用户管理 1、user1 2、user2 3、设置密码与删除用户 三、用户组管理 四、用户的切换 一、用户与用户组信息查看 查看用户&#xff0c;首先调出终端窗口&#xff0c;&#xff08;“sudo cat /etc/passwd”&#xff09;&#xff0c;输…

Day 50 小结

50.1 比较分析各种查找算法 顺序查找&#xff1a;时间复杂度&#xff1a;O(n)&#xff1b;可用于有序或无序数据&#xff1b;按顺序查找元素。 折半查找&#xff1a;时间复杂度&#xff1a;O(logn)&#xff1b;只能用于有序数据&#xff1b;从中间元素开始查找&#xff0c;每…

Linux 内核启动流程与入口函数分析

从启动引导程序 bootloader&#xff08;uboot&#xff09;跳转到 Linux 内核后&#xff0c;Linux 内核开始启动&#xff0c;今天我们分析一下 Linux 内核启动入口。 跳转过去初始化肯定是在汇编文件中&#xff0c;根据架构可以选择不同的平台&#xff0c;这里看一下链接汇编文…

STM32 Simulink 自动代码生成电机控制——记录一次电机初始位置检测及NS极的判断实验

目录 前言 基本原理 仿真实现 代码生成及开发板验证 前言 之前做了脉振高频注入的仿真到代码生成开发板运行的实验&#xff0c;电机可以通过高频注入计算出角度&#xff0c;但是在初始位置检测的时候&#xff0c;尝试了不少方法但是效果一般&#xff0c;很容易反转&#xff…

服务器模型 setsockopt 网络超时检测 广播组播和unix域套接字 5.23

四.服务器模型 1.循环服务器 TCP服务器 TCP服务器端运行后等待客户端的连接请求。 TCP服务器接受一个客户端的连接后开始处理&#xff0c;完成了客户的所有请求后断开连接。 TCP循环服务器一次只能处理一个客户端的请求。 只有在当前客户的所有请求都完成后&#xff0c;服务…

Lucene(6):分词器

1 分词理解 在对Document中的内容进行索引之前&#xff0c;需要使用分词器进行分词 &#xff0c;分词的目的是为了搜索。分词的主要过程就是先分词后过滤。 分词&#xff1a;采集到的数据会存储到document对象的Field域中&#xff0c;分词就是将Document中Field的value值切分…

netty学习第一课

技术主题 Netty是一个基于Java NIO&#xff08;非阻塞 I/O&#xff09;框架的网络编程框架。它提供了一系列的高级网络编程API&#xff0c;使得开发者可以非常容易地实现高性能、高可靠性的网络应用。Netty具有非常好的可扩展性和灵活性&#xff0c;能够很好地支持多种协议和数…

Fiddler抓包工具之fiddler的介绍及安装

Fiddler简介 Fiddler是比较好用的web代理调试工具之一&#xff0c;它能记录并检查所有客户端与服务端的HTTP/HTTPS请求&#xff0c;能够设置断点&#xff0c;篡改及伪造Request/Response的数据&#xff0c;修改hosts&#xff0c;限制网速&#xff0c;http请求性能统计&#xff…

从零实现一个数据库(DataBase) Go语言实现版 7.空闲列表: 重用页

英文源地址 由于我们的B树时不可变的, 每次对kv存储的更新都会在路径上创建新节点, 而不是更新当前节点, 从而使一些节点无法从最新版本访问到.我们需要从旧版本中重用这些不可访问的节点, 否则, 数据库文件将无限增长. 设计空闲列表 为了重用这些页, 我们将添加一个持久化存…

python处理字符串、文本实例及注释

1、多个界定符切割字符串 代码 line = asdf fjdk; afed, fjek,asdf, foo import re re.split(r[;,\s]\s*, line) 结果 在上面的例子中,分隔符可以是逗号,分号或者是空格,并且后面紧跟着任意个的空格。只要这个模式被找到,那么匹配的分隔符两边的实体都会被当成是结果中…

面了个20k的自动化测试,从腾讯出来的果然都有两把刷子···

现在找个会自动化测试的人真是难呀&#xff0c;10个里面有8个写了会自动化&#xff0c;但一问就是三不知 公司前段时间缺人&#xff0c;也面了不少测试&#xff0c;前面一开始瞄准的就是中级的水准&#xff0c;也没指望来大牛&#xff0c;提供的薪资在15-20k&#xff0c;面试的…

技巧:如何查看github的热门趋势和star排行

目录 1. 查看github的热门趋势2. 查看github的star排行3. 如何查看项目star增长曲线 1. 查看github的热门趋势 手动找到入口&#xff0c;打开github&#xff0c;登录后&#xff0c;找到Explore并点击进入&#xff0c;找到Trending切换&#xff0c;列出的就是github当天所有语言…

目标检测常用模型之R-CNN、Fast R-CNN、Faster R-CNN

文章目录 一、模型分类1. 一阶段目标检测2. 二阶段目标检测 二、常见模型1. R-CNN2. Fast R-CNN3. Faster R-CNN 一、模型分类 2012年卷积神经网络(Convolutional Neural Networks, CNNs)的兴起将目标检测领域推向了新的台阶。基于CNNs的目标检测算法主要有两条技术发展路线&am…