栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ map容器的简单用法

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ map容器的简单用法

C++ map容器的简单用法
  • 1.前言
  • 2.内容
    • map简介
    • map功能
    • map具体使用
      • 1.构造
      • 2.增加[插入]
        • 插入方法: insert方法 和 数组方法
      • 3.遍历 [正向、反向、数组方法遍历]
      • 4.查找
        • ①查找并返回key的迭代器 [find()]
          • 备注:此处迭代器为pair对象,所以用first ,second访问
        • ②仅判断是否存在key [count 、pair(lower_bound + upper_bound)]
      • 5.删除 [3种]
      • 6.swap() [两种]
      • 7.排序
  • 3.总结
  • 4.更新日志

1.前言

整理map的一些用法,欢迎指正~
有具体示例解释概念,欢迎品尝~

2.内容 map简介

map是STL的关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力 【key-value 】

map内部是一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能

map功能

查询(log(N))、插入、删除、更改、遍历

map具体使用 1.构造

头文件: < map >
示例

#include 
using namespace std;
#include 
typedef map MSI;  //为了使用方便,可进行类型起别名
int main()
{
	map m1;  //map构造函数
	MSI m2;
	return 0;
}
2.增加[插入]
#include 
using namespace std;
#include 
typedef map MSI;
typedef map::iterator MSIIT;
int main()
{
	map m1;  //map构造函数
	MSI m2;
	//四种插入方法
	//1.insert pair
	m2.insert(pair("ac", 4));

	//2.insert value_type
	m2.insert(map::value_type("as", 7));

	//3.数组
	m2["ak"] = 11;

	//4.{}
	m2.insert({ "ab",1 });

	//遍历 auto x=m2.begin() 也可
	for (MSIIT x = m2.begin(); x != m2.end(); x++)
		cout << x->first << " " << x->second << endl;
	return 0;
}

插入方法: insert方法 和 数组方法

区别:insert不可覆盖已经插入的数据,而数组方法可以
示例:

#include 
using namespace std;
#include 
typedef map MSI;
typedef map::iterator MSIIT;
int main()
{
	map m1;  //map构造函数
	MSI m2;
	//插入方法: insert方法 和 数组方法
	//1.insert pair
	m2.insert(pair("ac", 4));

	//2.insert value_type
	m2.insert(map::value_type("as", 7));

	//3.数组  
	m2["ak"] = 11;

	//4.{}
	m2.insert({ "ab",1 });

	
	//下面一行代码检检验是否成功插入
	//insert后返回iterator ,用 MSIIT接受 ,另一个bool则用来判断是否成功插入
	pair insert_pair;
	//1.
	insert_pair = m2.insert({ "ak",108 });  //由于上面已经插入了 “ak”,则此次insert失败
	if (insert_pair.second == true) puts("success!");
	else puts("failed!");

	//2.
	insert_pair = m2.insert({ "akkkk",108 });
	if (insert_pair.second == true) puts("success!");
	else puts("failed!");
	return 0;
}

3.遍历 [正向、反向、数组方法遍历]
#include 
using namespace std;
#include 
typedef map MSI;
typedef map MIS;
typedef map::iterator MSIIT;  //前向迭代器
typedef map::reverse_iterator MSIRIT; //反向迭代器
int main()
{
	map m1;  //map构造函数
	MSI m2;
	//插入
	m2["ak"] = 11;
	m2["axcv"] = 17;
	m2["zasfdxc"] = 21;
	m2["mnbvnvmk"] = 91;
	m2["bnmhk"] = 1;
	m2["vnmhk"] = 111;

	//遍历
	//正向遍历①  auto (常用)
	for (auto x : m2)
		cout << x.first << " " << x.second << endl;
	puts("");
	//正向遍历②  正向迭代器
	for (MSIIT x = m2.begin(); x != m2.end(); ++x)
		cout << x->first << " " << x->second << endl;
	puts("");
	//反向遍历 反向迭代器
	for (MSIRIT x = m2.rbegin(); x != m2.rend(); ++x)
		cout << x->first << " " << x->second << endl;
	puts("");

	//Specially 当 map 时,可以用数组遍历
	puts("");
	MIS m3;
	//插入
	m3[1] = "mvbc";
	m3[4] = "cvb";
	//对于MIS,不存在key的value默认为"" 空
	if (m3[2] == "") puts("none!");
	if (m3[78] == "") puts("none!");
	for (int i = 1; i <= 4; ++i)
		cout << i <<" "<< m3[i] << endl;

	return 0;
}


4.查找 ①查找并返回key的迭代器 [find()] 备注:此处迭代器为pair对象,所以用first ,second访问
#include 
using namespace std;
#include 
typedef map MSI;
typedef map::iterator MSIIT;
typedef map MIS;
int main()
{
	MSI m2;
	//插入
	m2["ak"] = 11;
	m2["axcv"] = 17;
	m2["zasfdxc"] = 21;
	m2["mnbvnvmk"] = 91;
	m2["bnmhk"] = 1;
	m2["vnmhk"] = 111;

	//无 "mua" 则,返回m2.end();
	MSIIT it = m2.find("mua");
	if (it != m2.end())  cout << "find ,its value is " << it->second << endl;
	else cout << "not find" << endl;
	
	//有 "ak" ,返回该位置的迭代器
	it = m2.find("ak");
	if (it != m2.end())  cout << "find ,its value is " << it->second << endl;
	else cout << "not find" << endl;

	return 0;
}

②仅判断是否存在key [count 、pair(lower_bound + upper_bound)]

方法1: count
map是一对一的映射关系,则count函数返回值 只可为 0 、1,即存在返回1,不存在返回0
示例:

#include 
using namespace std;
#include 
typedef map MSI;
typedef map::iterator MSIIT;
typedef map MIS;
int main()
{
	MSI m2;
	//插入
	m2["ak"] = 11;
	m2["axcv"] = 17;
	m2["zasfdxc"] = 21;
	m2["mnbvnvmk"] = 91;
	m2["bnmhk"] = 1;
	m2["vnmhk"] = 111;

	//无 "mua" 则
	int cnt = m2.count("mua");
	if (cnt)  cout << "find" << endl;
	else cout << "not find" << endl;

	//有 "ak" 
	cnt = m2.count("ak");
	if (cnt)  cout << "find" << endl;
	else cout << "not find" << endl;

	return 0;
}


方法2:pair
前置知识:
1.equal_range() :
在[left , right)序列中表示一个数值的第一次出现与最后一次出现的后一位。得到相等元素的子范围,将两个迭代器以pair形式返回
2.lower_bound()、upper_bound()
lower_bound()返回一个 iterator 它指向在[first,last)标记的有序序列中可以插入value,而不会破坏容器顺序的第一个位置,而这个位置标记了一个不小于value 的值 即,找到>=value的位置并返回
同理,upper_bound()找到>value的位置并返回

示例

#include 
using namespace std;
#include 
typedef map MSI;
typedef map::iterator MSIIT;
typedef map MIS;
int main()
{
	MSI m2;
	//插入
	m2["ak"] = 11;
	m2["axcv"] = 17;
	m2["zasfdxc"] = 21;
	m2["mnbvnvmk"] = 91;
	m2["bnmhk"] = 1;
	m2["vnmhk"] = 111;

	//先遍历输出排序后的结果,便于后续使用
	for (auto x : m2)
		cout << x.first << " " << x.second << endl;
	puts("");

	//当待查找的不存在时,lower_bound == upper_bound ,均返回 大于待查找的元素 的迭代器
	pair p = m2.equal_range("aka");  //两个迭代器,结合为pair形式返回
	cout << p.first->first << " " << p.first -> second << endl;
	cout << p.second->first << " " << p.second -> second << endl;

	puts("");

	//当 待查找的存在时, lower_bound != upper_bound 
	p = m2.equal_range("bnmhk");
	cout << p.first->first << " " << p.first->second << endl;
	cout << p.second->first << " " << p.second->second << endl;

	return 0;
}

正文:

#include 
using namespace std;
#include 
typedef map MSI;
typedef map::iterator MSIIT;
typedef map MIS;
int main()
{
	MSI m2;
	//插入
	m2["ak"] = 11;
	m2["axcv"] = 17;
	m2["zasfdxc"] = 21;
	m2["mnbvnvmk"] = 91;
	m2["bnmhk"] = 1;
	m2["vnmhk"] = 111;

	//先遍历输出排序后的结果,便于后续使用
	for (auto x : m2)
		cout << x.first << " " << x.second << endl;
	puts("");

	//当待查找的不存在时,lower_bound == upper_bound ,均返回 大于待查找的元素 的迭代器
	pair p = m2.equal_range("aka");  //两个迭代器,结合为pair形式返回
	if (p.first != p.second) puts("find!");
	else puts("not find");

	puts("");

	//当 待查找的存在时, lower_bound != upper_bound 
	p = m2.equal_range("bnmhk");
	if (p.first != p.second) puts("find!");
	else puts("not find");

	return 0;
}

5.删除 [3种]

1.iterator erase(iterator it);//通过一个迭代器删除
2.iterator erase(iterator first,iterator last)//删除一个范围的元素
3.size_type erase(const Key&key); //通过关键字删除
clear()就相当于Map.erase(Map.begin(),Map.end());
示例:

#include 
using namespace std;
#include 
typedef map MSI;
typedef map::iterator MSIIT;
typedef map MIS;
int main()
{
	MSI m2;
	//插入
	m2["ak"] = 11;
	m2["axcv"] = 17;
	m2["zasfdxc"] = 21;
	m2["mnbvnvmk"] = 91;
	m2["bnmhk"] = 1;
	m2["vnmhk"] = 111;

	//先遍历输出排序后的结果,便于后续使用
	for (auto x : m2)
		cout << x.first << " " << x.second << endl;
	puts("");

	//1.迭代器 iterator
	MSIIT it = m2.find("mnbvnvmk");  //找到位置
	m2.erase(it);

	//2.关键字 
	int t1=m2.erase("mnbvnvmk");  //已经被删除过了,则此次erase无效,返回0
	int t2 = m2.erase("vnmhk");    //成功erase ,返回1
	cout << t1 << " " << t2 << endl;

	for (auto x : m2)
		cout << x.first << " " << x.second << endl;
	puts("");

	return 0;
}

#include 
using namespace std;
#include 
typedef map MSI;
typedef map::iterator MSIIT;
typedef map MIS;
int main()
{
	MSI m2;
	//插入
	m2["ak"] = 11;
	m2["axcv"] = 17;
	m2["zasfdxc"] = 21;
	m2["mnbvnvmk"] = 91;
	m2["bnmhk"] = 1;
	m2["vnmhk"] = 111;

	//先遍历输出排序后的结果,便于后续使用
	for (auto x : m2)
		cout << x.first << " " << x.second << endl;
	puts("");

	m2.clear();
	cout << "=====清空后=====" << endl;
	for (auto x : m2)
		cout << x.first << " " << x.second << endl;
	puts("");

	return 0;
}

6.swap() [两种]

swap的作用是,交换两个容器内的所有元素

#include 
using namespace std;
#include 
typedef map MSI;
typedef map::iterator MSIIT;
typedef map MIS;
int main()
{
	MSI m1,m2;
	//插入
	m1["a"] = 1;
	m1["b"] = 1;
	m1["c"] = 1;
	m1["d"] = 1;

	m2["ak"] = 11;
	m2["axcv"] = 17;
	m2["zasfdxc"] = 21;
	m2["mnbvnvmk"] = 91;
	m2["bnmhk"] = 1;
	m2["vnmhk"] = 111;

	//先遍历输出排序后的结果,便于后续使用
	for (auto x : m1)
		cout << x.first << " " << x.second << endl;
	puts("");
	//先遍历输出排序后的结果,便于后续使用
	for (auto x : m2)
		cout << x.first << " " << x.second << endl;
	puts("");

	//swap
	m1.swap(m2);
	//也可以 : swap(m1, m2);

	//swap后
	for (auto x : m1)
		cout << x.first << " " << x.second << endl;
	puts("");
	//先遍历输出排序后的结果,便于后续使用
	for (auto x : m2)
		cout << x.first << " " << x.second << endl;
	puts("");

	return 0;
}


其实直接用swap()是一样的
如果用map函数可以实现的功能,而STL Algorithm也可以完成该功能,建议用map自带函数,效率高一些。

7.排序

默认按key升序排序,不可使用sort

当,关键字为 结构体时,insert等会通不过, 此时要重载 < 号
如果不重载<号,VS2019会报以下错误:

重载 <

#include 
using namespace std;
#include 
typedef map MSI;
typedef map::iterator MSIIT;
typedef map MIS;
//要求的排序方法:先id升序,若id相同,则name升序
typedef struct Student {
	int id;
	string name;
	bool operator <(Student const& s1) const  //重载 <
	{
		if (id < s1.id) return true;
		if (id == s1.id)
			//string 的 compare函数 前小后大为-1 相等为0 前大后小为1
			return name.compare(s1.name) < 0;  
		return false;
	}
}stu;

int main()
{
	stu s1, s2, s3;
	s1.id = 1;
	s1.name = "a";
	s2.id = 2;
	s2.name = "b";
	s3.id = 1;
	s3.name = "ac";

	map m1;   //学生信息,以及分数
	m1.insert({ s1,20 });
	m1.insert({ s2,98 });
	m1.insert({ s3,9 });

	//x为pair类型变量 直接 . 访问
	for (auto x : m1)
		cout << x.first.id << " " < 

3.总结
 C++ maps是一种关联式容器,包含“关键字 key/值 value”对  [键值对]
map中由于它内部有序,是由红黑树保证,因此很多函数执行的时间复杂度都是log2N的

 begin()         返回指向map头部的迭代器
 end()           返回指向map末尾的迭代器
 
 size()          返回map中元素的个数
 
 clear()        删除所有元素

 count()         返回指定元素出现的次数

 empty()         判断map是否为空 [map为空则返回true]
 
 insert()        插入元素

 erase()         删除一个元素

 find()          查找一个元素
 
 rbegin()        返回一个指向map尾部的逆向迭代器
 rend()          返回一个指向map头部的逆向迭代器
 
 lower_bound()   返回键值>=给定元素的第一个位置
 upper_bound()    返回键值>给定元素的第一个位置
 	 
 max_size()      返回可以容纳的最大元素个数
 swap()           交换两个map
 
 equal_range()   返回特殊条目的迭代器对
 get_allocator() 返回map的配置器

 key_comp()      返回比较元素key的函数
 value_comp()     返回比较元素value的函数
4.更新日志

2022.8.7 整理

欢迎评论留言、指正~~

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1038319.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号