C++STL map/multimap容器 构造与赋值 大小与交换 插入和删除查找和统计 内置数据类型和自定义数据类型排序

map/multimap容器

文章目录

  • map/multimap容器
    • 1 map基本概念
    • 2 map构造和赋值
    • 3 map大小和交换
    • 4 map插入和删除
    • 5 map查找和统计
    • 6 map容器排序

1 map基本概念

简介:

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

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

优点: 可以根据key值快速找到value值,高性能、高效率

map和multimap区别:

  • map不允许容器中有重复key值元素,value值是可以重复的
  • multimap允许容器中有重复key值元素

2 map构造和赋值

功能描述: 对map容器进行构造和赋值操作

构造函数原型:

  • map mp; //map默认构造函数:
  • map(const map &mp); //拷贝构造函数

赋值函数原型:

  • map& operator=(const map &mp); //重载等号操作符

代码示例:

//map 构造和赋值
void test1()
{
	//创建map容器
	cout << "默认构造 m1" << endl;
	map<int, int> m1;
	//所有元素都是对组pair,因此插入时使用pair
	//pair有两个数据,一个对应map的key,一个对应map的value。通过key快速索引到value
	//以下方式相当于创建一个匿名对组,匿名对组再放进容器中
	//插入时,会自动按照升序给key值排序放进容器中
	m1.insert(pair<int, int>(1, 21));
	m1.insert(pair<int, int>(4, 28));
	m1.insert(pair<int, int>(2, 23));
	m1.insert(pair<int, int>(3, 25));
	m1.insert(pair<int, int>(5, 30));
	printMap(m1);

	//拷贝构造
	map<int, int>m2(m1);
	cout << "\n拷贝构造 m2" << endl;
	printMap(m2);

	//赋值
	map<int, int>m3;
	m3 = m2;
	cout << "\n赋值操作 m3" << endl;
	printMap(m3);
}

C++STL map/multimap容器 构造与赋值 大小与交换 插入和删除查找和统计 内置数据类型和自定义数据类型排序_第1张图片

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

3 map大小和交换

功能描述: 统计map容器大小以及交换map容器

函数原型:

  • size(); //返回容器中元素的数目
  • empty(); //判断容器是否为空
  • swap(st); //交换两个集合容器

代码示例:

void printMap(const map<int, int>& m)
{
	for (map<int, int>::const_iterator it = m.begin(); it != m.end(); it++)
	{
		cout << "key = " << (*it).first << "\tvalue = " << it->second << endl;
	}
	cout << endl;
}

//map 大小和交换
void test1()
{
	//创建map容器
	map<int, int> m1;
	cout << "插值前 m1  ";
	if (m1.empty())
	{
		cout << "容器为空!" << endl;
	}
	else
	{
		cout << "容器不为空,容器大小为:" << m1.size() << endl;
	}
	m1.insert(pair<int, int>(1, 21));
	m1.insert(pair<int, int>(4, 28));
	m1.insert(pair<int, int>(2, 23));
	m1.insert(pair<int, int>(3, 25));
	m1.insert(pair<int, int>(5, 30));
	cout << "插值前 m1  ";
	if (m1.empty())
	{
		cout << "容器为空!" << endl;
	}
	else
	{
		cout << "容器不为空,容器大小为:" << m1.size() << endl;
	}
	printMap(m1);
	cout << string(40, '*') << endl;

	//交换
	cout << "\n交换前" << endl;
	cout << "m2" << endl;
	map<int, int>m2;
	m2.insert(pair<int, int>(1, 100));
	m2.insert(pair<int, int>(4, 400));
	m2.insert(pair<int, int>(2, 200));
	m2.insert(pair<int, int>(3, 300));
	m2.insert(pair<int, int>(5, 500));
	printMap(m2);

	cout << "m3" << endl;
	map<int, int>m3;
	m3.insert(pair<int, int>(1, 25));
	m3.insert(pair<int, int>(3, 30));
	m3.insert(pair<int, int>(2, 28));
	printMap(m3);
	cout << string(40, '*') << endl;
	cout << "\n交换后\nm2" << endl;
	m3.swap(m2);
	printMap(m2);
	cout << "m3" << endl;
	printMap(m3);
}

C++STL map/multimap容器 构造与赋值 大小与交换 插入和删除查找和统计 内置数据类型和自定义数据类型排序_第2张图片

总结:

  • 统计大小 — size
  • 判断是否为空 — empty
  • 交换容器 — swap

4 map插入和删除

功能描述: map容器进行插入数据和删除数据

函数原型:

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

代码示例:

void printMap(const map<int, int>& m)
{
	for (map<int, int>::const_iterator it = m.begin(); it != m.end(); it++)
	{
		cout << "key = " << (*it).first << "\tvalue = " << it->second << endl;
	}
	cout << endl;
}
//map 插入 删除
void test1()
{
	int n = 20;
	map<int, int> m1;
	cout << "m1" << endl;

	m1.insert(pair<int, int>(1, 21));//第一种
	m1.insert(make_pair(4, 28));//第二种 不用写模板参数 直接写key和value
	m1.insert(map<int, int>::value_type(2, 23));//第三种 
	m1.insert(make_pair(5, 30));
	m1.insert(make_pair(6, 18));
	//[]这种方式不建议插值 可以用来访问value
	m1[3] = 25;//第四种 中括号[] 如果容器没有这个key 会创建一个该key对应的value为0的对组 (key, 0)
	//cout << m1[7] << endl;//创建value为0的对组
	printMap(m1);
	cout << string(n, '*') << endl;

	//删除
	map<int, int> m2;
	m2 = m1;
	cout << "迭代器传入 删除" << endl;
	m2.erase(m2.begin());//删除第一个元素
	printMap(m2);

	cout << "指定key值 删除" << endl;
	m2.erase(6);//按照key值删除
	printMap(m2);

	cout << "区间传入 删除" << endl;
	map<int, int>::iterator it = m2.begin();
	it++;
	m2.erase(it, m2.end());
	//m2.erase(m2.begin(), m2.end());//按照key区间删除 相当于清空
	printMap(m2);

	cout << "清空" << endl;
	//m2.erase(m2.begin(), m2.end());//按照key区间删除 相当于清空
	m2.clear();
	printMap(m2);
}

C++STL map/multimap容器 构造与赋值 大小与交换 插入和删除查找和统计 内置数据类型和自定义数据类型排序_第3张图片
注意点: []这种方式不建议插值 可以用来访问value,如果容器没有这个key 会创建一个该key对应的value为0的对组 (key, 0)。
C++STL map/multimap容器 构造与赋值 大小与交换 插入和删除查找和统计 内置数据类型和自定义数据类型排序_第4张图片
总结:

  • map插入方式很多,记住其一即可
  • 插入 — insert
  • 删除 — erase
  • 清空 — clear

5 map查找和统计

功能描述: 对map容器进行查找数据以及统计数据

函数原型:

  • find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
  • count(key); //统计key的元素个数。对map而言,结果是0或1,map不允许有重复key值;multimap允许有重复key值,结果有可能大于1。

代码示例:

void printMap(const map<int, int>& m)
{
	for (map<int, int>::const_iterator it = m.begin(); it != m.end(); it++)
	{
		cout << "key = " << (*it).first << "\tvalue = " << it->second << endl;
	}
	cout << endl;
}


void test1()
{
	int n = 50;

	//查找
	map<int, int> m1;
	cout << "m1" << endl;
	m1.insert(make_pair(2, 28));
	m1.insert(make_pair(4, 28));
	m1.insert(make_pair(5, 30));
	m1.insert(make_pair(6, 18));
	printMap(m1);

	cout << "查找key为5的元素  ";
	map<int, int>::iterator pos = m1.find(5);//无论找到与否 返回值是一个迭代器
	if (pos != m1.end())
	{
		cout << "查找成功!key = " << pos->first << "value = " << pos->second << endl;
	}
	else
	{
		cout << "查找失败!" << endl;
	}

	cout << "查找key为3的元素  ";
	map<int, int>::iterator pos2 = m1.find(3);//无论找到与否 返回值是一个迭代器
	if (pos2 != m1.end())
	{
		cout << "查找成功!key = " << pos2->first << "value = " << pos2->second << endl;
	}
	else
	{
		cout << "查找失败!" << endl;
	}
	cout << string(n, '*') << endl;
	//统计
	m1.insert(make_pair(6, 20));
	cout << "map      m1" << endl; printMap(m1);
	int ret1 = m1.count(6);
	
	multimap<int, int>m2;
	m2.insert(make_pair(1, 100));
	m2.insert(make_pair(2, 200));
	m2.insert(make_pair(3, 300));
	m2.insert(make_pair(3, 400));
	m2.insert(make_pair(5, 400));
	cout << "multimap m2" << endl;
	for (multimap<int, int>::iterator it = m2.begin(); it != m2.end(); it++)
	{
		cout << "key = " << (*it).first << "\tvalue = " << it->second << endl;
	}
	cout << endl;
	int ret2 = m2.count(3);

	cout << "m1中key为6的元素个数为:" << ret1 << endl;
	cout << "m1中key为3的元素个数为:" << ret2 << endl;
	cout << string(n, '*') << endl;
}

C++STL map/multimap容器 构造与赋值 大小与交换 插入和删除查找和统计 内置数据类型和自定义数据类型排序_第5张图片

总结:

  • 查找 — find (返回的是迭代器)
  • 统计 — count (对于map,结果为0或者1)

6 map容器排序

学习目标: map容器默认排序规则为 按照key值进行 从小到大排序,掌握如何改变排序规则

主要技术点: 利用仿函数,可以改变排序规则

代码示例:

void printMap(const map<int, int>& m)
{
	for (map<int, int>::const_iterator it = m.begin(); it != m.end(); it++)
	{
		cout << "key = " << (*it).first << "\tvalue = " << it->second << endl;
	}
	cout << endl;
}

class myCompare
{
public:
	bool operator()(int v1, int v2) const
	{
		return v1 > v2;
	}
};

class Person
{
public:
	Person(string name, int weight)
	{
		this->m_name = name;
		this->m_weight = weight;
	}
	string m_name;
	int m_weight;
};

class myCompare2
{
public:
	bool operator()(const Person& p1, const Person& p2) const
	{
		return p1.m_weight > p2.m_weight;
	}
};

void test1()
{
	int n = 50;

	cout << "内置数据类型" << endl;
	map<int, int> m1;
	m1.insert(make_pair(2, 28));
	m1.insert(make_pair(1, 25));
	m1.insert(make_pair(3, 23));
	m1.insert(make_pair(4, 28));
	m1.insert(make_pair(5, 30));
	m1.insert(make_pair(6, 18));

	cout << "默认规则 按照key值 升序规则 插入数据 m1" << endl;
	printMap(m1);
	cout << string(n, '-') << endl << endl;

	cout << "制定规则 按照key值 降序规则 插入数据 m2" << endl;
	map<int, int, myCompare>m2;
	m2.insert(make_pair(2, 28));
	m2.insert(make_pair(1, 25));
	m2.insert(make_pair(3, 23));
	m2.insert(make_pair(4, 28));
	m2.insert(make_pair(5, 30));
	m2.insert(make_pair(6, 18));
	for (map<int, int, myCompare>::iterator it = m2.begin(); it != m2.end(); it++)
	{
		cout << "key = " << (*it).first << "\tvalue = " << it->second << endl;
	}
	cout << endl;
	cout << string(n, '-') << endl << endl;

	cout << "自定义数据类型 按照key值  m3" << endl;
	Person p1("西施", 54);
	Person p2("貂蝉", 55);
	Person p3("杨玉环", 60);
	Person p4("王昭君", 56);
	map<int, Person, myCompare> m3;
	m3.insert(make_pair(1, p1));
	m3.insert(make_pair(2, p2));
	m3.insert(make_pair(3, p3));
	m3.insert(make_pair(4, p4));
	for (map<int, Person, myCompare>::iterator it = m3.begin(); it != m3.end(); it++)
	{
		cout << "key = " << (*it).first << "\t姓名:" << ((*it).second).m_name << "\t年龄:" << ((*it).second).m_weight << endl;
	}
	cout << endl;
	cout << string(n, '-') << endl << endl;

	cout << "自定义数据类型 按照体重  m4" << endl;
	map<Person, int, myCompare2> m4;
	m4.insert(make_pair(p1, 1));
	m4.insert(make_pair(p2, 2));
	m4.insert(make_pair(p3, 3));
	m4.insert(make_pair(p4, 4));
	for (map<Person, int, myCompare2>::iterator it = m4.begin(); it != m4.end(); it++)
	{
		cout << "key = " << (*it).second << "\t姓名:" << ((*it).first).m_name << "\t年龄:" << ((*it).first).m_weight << endl;
	}
	cout << endl;
	cout << string(n, '-') << endl << endl;
}

C++STL map/multimap容器 构造与赋值 大小与交换 插入和删除查找和统计 内置数据类型和自定义数据类型排序_第6张图片

总结:

  • 利用仿函数可以指定map容器的排序规则
  • 对于自定义数据类型,map必须要指定排序规则,同set容器

你可能感兴趣的:(C++,泛型编程,语法学习笔记,c++)