C++ STL学习:map容器

一、map容器基本知识

1、基本概念:

  • map中所有的元素都是pair
  • pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
  • 所有元素都会根据元素的键值自动排序
  • 头文件是<map>

2、本质:

  • map/multimap属于关联式容器,底层结构使用二叉树实现。

3、优点:

  • 可以根据key值快速找到value值
  • map和multimap的区别:
    • map不允许容器中有重复key值元素
    • multimap允许容器中有重复key值元素

二、map构造和赋值

两种方式构造:

//map<T1,T2> mp;//默认构造函数
//map(const map &mp);//拷贝构造函数

赋值:

map& operator=(const map &mp);//重载等号操作符
#include <map>

void printMap(map<int,int>&m)
{
//掌握如何遍历!!!!!!!!!!!!!
	for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
	{
		cout << "key = " << it->first << " value = " << it->second << endl;
	}
	cout << endl;
}

void test01()
{
	map<int,int>m; //默认构造
	m.insert(pair<int, int>(1, 10));//pair对组
	m.insert(pair<int, int>(2, 20));
	m.insert(pair<int, int>(3, 30));
	printMap(m);

	map<int, int>m2(m); //拷贝构造
	printMap(m2);

	map<int, int>m3;
	m3 = m2; //赋值
	printMap(m3);
}

int main() {

	test01();

	system("pause");

	return 0;
}

总结:map中所有元素都是成对出现,插入数据时候要使用对组。

三、map大小和交换

函数原型:

  • size();//返回容器中元素的数目
  • empty();//判断容器是否为空
  • swap(st);//交换两个集合容器
#include<iostream>
using namespace std;
#include <map>

//大小
void tset1()
{
	map<int,int>m;
	m.insert(pair<int,int>(1,10));
	m.insert(pair<int,int>(2,20));
	m.insert(pair<int,int>(3,30));
	if(m.empty())
	{
		cout<<"m为空"<<endl;
	}
	else
	{
		cout<"m不为空"<<endl;
		cout<<"m大小为:"<<m.size()<<endl;
	}
}
//输出函数
void printmap(map<int,int>&m)
{
	for(map<int,int>::iterator it=m.begin();it!=m.end();it++)
	{
		cout<<"key="<<it->first<<"value="<<it->second<<endl;
}
}
//交换
void test2()
{
	map<int,int>m1;
	m1.insert(pair<int,int>(1,10));
	m1.insert(pair<int,int>(2,20));
	m1.insert(pair<int,int>(3,30));
	
	map<int,int>m2;
	m2.insert(pair<int,int>(4,40));
	m2.insert(pair<int,int>(5,50));
	m2.insert(pair<int,int>(6,60));
	
	cout<<"交换前"<<endl;
	printmap(m1);	printmap(m1);
	cout<<"交换后"<<endl; 
	m1.swap(m2);//互相交换
	printmap(m1);	printmap(m1);
}

四、map插入和删除

函数原型:

  • insert(elem);//插入元素
  • clear();//清除所有元素
  • erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器
  • erase(beg,end);//删除区间[beg,end]的所有元素,返回下一个元素的迭代器
  • erase(key);//删除容器中值为key的元素
#include <iostream>
using namespace std;
#include <map>

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

//插入
void test1()
{
	map<int,int>m;
	//第一种
	m.insert(pair<int,int>(1,10))
	//第二种	
	m.insert(make_pair(2,20));
	//第三种
	m.insert(map<int,int>::value_type(3,30));
	//第四种
	m[4]=40;//最简单但是不建议用于插入(因为容易出错),但可以用于根据key访问value值
	//删除
	m.erase(m.begin());
	printmap(m);
	
	m.erase(3)//按照key来删除
	printmap(m)
	//等价于m.clear()
	m.erase(m.begin(),m.end());
	printmap(m);
}


int main()
{
	test1();
	printmap();
	return ;0
}

五、map查找和统计

函数原型:

  • find(key) //查找key是都存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
  • count(key) //统计key的元素个数(map只能是0或1)
#include<iostream>
using namespace std;
#include <map>

void test1()
{
	//查找
	map<int,int>m;
	m.insert(pair<int,int>(1,10));
	m.insert(pair<int,int>(3,30));
	m.insert(pair<int,int>(2,20));
	map<int,int>::iterator pos = m.find(3);//!!!千万记住返回的是一个迭代器m.find()->->operator pos!!!
	if(pos!=m.end())
	{
		cout<<"查到了元素key"<<(*pos).first<<"value="<<pos->second<<endl;
	}
	else
	{
		cout<<"未找到元素"<<endl;
	}
	//统计
	//map不允许插入重复key元素,count统计为0或1
	//multimap的count统计可能大于一
	int num=m.count(3);
	cout<<"num="<<num<<endl;
}

六、map容器排序

  • 利用仿函数,可以改变排序规则
#include <iostream>
using mamespace std;
#include <map>
//仿函数。利用仿函数进行排序
class mycompare
{
public:
	bool operator()(int v1,int v2)
	{
		//降序
		return v1>v2;
	}
}
//排序
void test1()
{
	map<int,int,mycompare>m;	//!!!没有第三个参数时,默认为升序排序
	m.insert(make_pair(1,10));
	m.insert(make_pair(2,20));
	m.insert(make_pair(3,30));
	m.insert(make_pair(4,40));
	for(map<int,int,mycompare>m::iterator it=m.begin();it!=m.end(),it++)	//这里遍历也要加第三个参数
	{
		cout<<"key="<<it->first<<"value="<<it->second<<endl;
	}
}
int main()
{
	test1();
	return 0;
}

七、产生随机数

·由于下面的例子要用到随机数,所以先熟悉一下随机数的产生
·C++中没有自带的random函数,要实现随机数的生成就需要使用rand()和srand()。
·不过,由于rand()的内部实现是用线性同余法做的,所以生成的并不是真正的随机数,而是在一定范围内可看为随机的伪随机数。
·rand()会返回一随机数值, 范围在0至RAND_MAX 间。RAND_MAX定义在stdlib.h, 其值为2147483647。因为没有随机种子所以,每次运行结果都一样,因此要是有srand()
·srand()可用来设置rand()产生随机数时的随机数种子。通过设置不同的种子,我们可以获取不同的随机数序列。
·可以利用srand((int)(time(NULL))的方法,利用系统时钟,产生不同的随机数种子。不过要调用time(),需要加入头文件< ctime >。
在这里插入图片描述

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    srand((int)time(0));  // 产生随机种子  把0换成NULL也行
    for (int i = 0; i < 10; i++)
    {
        cout << rand()%100<< " ";
    }
    return 0;
}

产生一定范围随机数的通用表示公式是:
要取得[0,n) 就是rand()%n 表示 从0到n-1的数
要取得[a,b)的随机整数,使用(rand() % (b-a))+ a;
要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a;
要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1;
通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。
要取得a到b之间的随机整数,另一种表示:a + (int)b * rand() / (RAND_MAX + 1)。 可以用宏定义表示:#define random(a,b) (rand()%(b-a)+a)
要取得0~1之间的浮点数,可以使用rand() / double(RAND_MAX)。
参考:https://www.cnblogs.com/xiaokang01/p/9786751.html

八、案例:员工分组

要求:

  • 公司今天招聘了10个员工(ABCDEFGHIJ),10名员工进入公司之后,需要指派员工在那个部门工作
  • 员工信息有: 姓名 工资组成;部门分为:策划、美术、研发
  • 随机给10名员工分配部门和工资
  • 通过multimap进行信息的插入 key(部门编号) value(员工)
  • 分部门显示员工信息
    步骤:
  • 创建10名员工,放到vector中
  • 遍历vector容器,取出每个员工,进行随机分组
  • 分组后,将员工部门编号作为key,具体员工作为value,放入到multimap容器中
  • 分部门显示员工信息
#include<iostream>
#include<vector>
#include<string>
#include<map>
#include<ctime>
using namespace std;

//!!!!!!!!!!!!!!!!来个宏定义!!!!!!!!!!!!!!有点忘了,要记住,重新熟悉
#define cehua 0
#define meishu 1
#define yanfa 2

class worker
{
public:
	string name;
	int salary;
};
//随机创建员工
void createworker(vector<worker>&v)
{
	string nameseed="ABCDEFGHIJ";
	for(int i=0;i<10;i++)
	{
		worker worker;
		worker.name="员工";
		worker.name+=nameseed[i];
		
		worker.salary=rand()%10000+10000;//10000-19999的随机数,必须加上srand((unsigned int)time(NULL))才会产生不一样的随机数,后面有加!!!!!!!!!!!!!!
		//将员工放入容器中
		v.push_back(worker);
	}
}

//员工分组
void setgroup(vector<worker>&v,multimap<int,worker>&m)
{
	for(vector<worker>::iterator it=v.begin();it!=v.end();it++)
	{
		//随机产生部门编号
		int depid=rand%3;	//0-2
		//将员工插入到分组中
		//key部门编号,value具体员工
		m.insert(make_pair(depid,*it))
	}
}
void showworkerbygroup(multimap<int,worker>&m)
{
	cout<<"策划部门"<<endl;
	multimap<int,worker>::iterator pos=m.find(cehua);
	int count=m.count(cehua);	//统计具体人数
	in index=0;
	for(;pos!m.end()&&index<count;pos++,index++)
	{
		cout<<"姓名:"<<pos->second.name<<"工资:"<<pos->second.salary<<endl;
	}
	cout<<"============================================================"<<endl;
	cout<<"美术部门"<<endl;
	multimap<int,worker>::iterator pos=m.find(meishu);
	int count=m.count(meishu);	//统计具体人数
	in index=0;
	for(;pos!m.end()&&index<count;pos++,index++)
	{
		cout<<"姓名:"<<pos->second.name<<"工资:"<<pos->second.salary<<endl;
	}
	cout<<"=============================================================="<<endl;
	cout<<"研发部门"<<endl;
	multimap<int,worker>::iterator pos=m.find(yanfa);
	int count=m.count(yanfa);	//统计具体人数
	in index=0;
	for(;pos!m.end()&&index<count;pos++,index++)
	{
		cout<<"姓名:"<<pos->second.name<<"工资:"<<pos->second.salary<<endl;
	}
}

int main()
{
	srand((unsigned int)time(NULL));//!!!!!!!!每次产生不一样的随机数!!!!!!!!!!

	//1
	vector<worker> vworker;
	creatworker(vworker);
	//2
	multimap<int,worker>mworker;
	setgroup(vworker,mworker);
	//3
	showworkerbygroup(mworker);
	system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值