map容器的基本使用


map和set容器,multimap和multiset是树形结构的关联式容器,这四种容器底层原理都是红黑树,容器中的元素是一个有序序列。

map

1.map是关联式容器,它是按照特定的次序(按照key来比较),存储由键key和值value组成的键值对
2.在map中,键值key通常用于排序和唯一的标识元素,而value中存储与此键值key关联的内容。键值key和value的类型可能不同,并且在map内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair:
typedef pair<const key, T> value_type;
3.在内部,map中的元素总是按照键值key进行比较排序的
4.map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
5. map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

map模板参数

在这里插入图片描述
Compare:仿函数,缺省参数为less,默认是以升序(对于string是字典序)排序的,我们可以给该类型传递参数greater,将容器中的顺序改为降序。如果无法比较时(自定义类型),需要用户自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)

默认构造

在这里插入图片描述
1.空的map
2.使用区间来初始化
3.拷贝构造
4.移动语义
5.可变参数列表初始化

map<string, string> m1;//空容器

vector<pair<string, string>> v{ {"hello", "你好"}, {"sort", "排序" }};
/*cout << (*v.begin()).first << endl;
cout << (*v.begin()).second << endl;*/
map<string, string> m2(v.begin(), v.end());//区间初始化
map<string, string> m3(m2);

map<string, string> m4{ { "hello", "你好" }, { "sort", "排序" } };//可变参数列表初始化

迭代器

在这里插入图片描述
begin:返回容器的第一个元素位置
end:返回容器最后一个元素的下一个位置
rbegin:返回最后一个元素位置------底层其实是返回的end() - 1
rend:返回第一个元素的前一个位置------底层其实是返回的begin()-1
c:返回的是const迭代器,元素不可以被修改
迭代器具体实现请阅读C++迭代器底层实现

[ ]

map允许根据key值直接访问对应的value
在这里插入图片描述
在这里插入图片描述

int main()
{
	map<string, string> dict;
	dict.insert(make_pair("string", "字符串"));
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("insert", "插入"));
	dict["string"];		//查找和读
	dict["map"];		//插入
	dict["map"] = "地图,映射";//修改
	dict["set"] = "集合";//插入 + 修改
	return 0;
}

在这里插入图片描述
map容器[]的底层是通过insert来实现的
底层

V& operator[](const K& key)
{
	pair<iterator, bool> ret = insert(make_pair(key, V()));
	return ret.first->second;
}

在使用[],当map中不存在对应的key时,会将该key值插入到map中,value此时传的是value对应类型的匿名对象
operator[]的返回值value

map<string, string> m1{ { "hello", "你好" }, { "sort", "排序" } };
string ret = m1["sort"];//根据[]直接访问元素
cout << ret << endl;
m1["hello"] = "你好!";//修改key值对应的value
cout << m1["hello"] << endl;

map允许通过key对应的修改value

int main()
{
	map<string, string> dict;
	dict.insert(make_pair("string", "字符串"));
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("insert", "插入"));
	dict["string"];		//查找和读
	dict["map"];		//插入
	dict["map"] = "地图,映射";//修改
	dict["set"] = "集合";//插入 + 修改
	return 0;
}

{ }

map<string, string> m;
m.insert({"insert", "插入"});

C++11支持{ },多参数的构造函数隐式类型转换,在底层会将{}转化为make_pair

insert

在这里插入图片描述
map的插入,插入的是键值对
在这里插入图片描述
1.插入一个键值对
3.插入一个区间
4.插入一个可变参数列表

map<string, string> m1{ { "hello", "你好" }, { "sort", "排序" } };
m1.insert(make_pair("David", "戴维"));
for (auto& e : m1)
{
	cout << e.first << ": " << e.second << endl;
}
return 0;

在这里插入图片描述

map<string, string> m1{ { "hello", "你好" }, { "sort", "排序" } };
m1.insert(make_pair("David", "戴维"));//插入单个键值对
for (auto& e : m1)
{
	cout << e.first << ": " << e.second << endl;
}
map<string, string> m2;
m2.insert(m1.begin(), m1.end());//插入一个区间
for (auto& e : m2)
{
	cout << e.first << ": " << e.second << endl;
}
for (auto& e : m2)
{
	cout << e.first << ": " << e.second << endl;
}
map<string, string> m3;
m3.insert({ { "hello", "你好" }, { "sort", "排序" } });//插入一个可变参数列表
for (auto& e : m3)
{
	cout << e.first << ": " << e.second << endl;
}

erase

在这里插入图片描述

map<string, string> m1{ { "hello", "你好" }, { "sort", "排序" }, {"David", "戴维"}, {"leave", "离开"} };

for (auto& e : m1)
{
	cout << e.first << ": " << e.second << endl;
}

map<string, string>::iterator it = m1.begin();
m1.erase(it);//根据迭代器的指向删除对应的键值对
m1.erase("leave");//根据key删除键值对
cout << endl;
for (auto& e : m1)
{
	cout << e.first << ": " << e.second << endl;
}
it = m1.begin();
m1.erase(++it, m1.end());//删除某一个区间
cout << endl;
for (auto& e : m1)
{
	cout << e.first << ": " << e.second << endl;
}

find

在这里插入图片描述
find返回值为指向该键值对的迭代器指针

map<string, string> m1{ { "hello", "你好" }, { "sort", "排序" }, {"David", "戴维"}, {"leave", "离开"} };
map<string, string>::iterator it = m1.find("sort");//通过key找到对应的键值对
cout << (*it).first << ": " << (*it).second << endl;
if (it != m1.end())
{
	m1.erase(it);
}

lower_bound && upper_bound

下界
在这里插入图片描述
上界:在这里插入图片描述

map<string, string> m1{ {"David", "戴维"}, { "hello", "你好" }, {"leave", "离开"}, { "sort", "排序" }  };
map<string, string>::iterator lower_it1 = m1.lower_bound("hello");
map<string, string>::iterator lower_it2 = m1.lower_bound("i");
cout << (*lower_it1).first << " " << (*lower_it1).second << endl;//hello : 你好
cout << (*lower_it2).first << " " << (*lower_it2).second << endl;//leave : 离开
cout << endl;
map<string, string>::iterator upper_it1 = m1.upper_bound("hello");
map<string, string>::iterator upper_it2 = m1.upper_bound("i");
cout << (*upper_it1).first << " " << (*upper_it1).second << endl;//leave : 离开
cout << (*upper_it2).first << " " << (*upper_it2).second << endl;//leave : 离开

map中的数据默认是以字典序进行排序的

map<string, string> m1{ { "hello", "你好" }, { "sort", "排序" }, {"David", "戴维"}, {"leave", "离开"} };
map<string, string, greater<string>> m2{ { "hello", "你好" }, { "sort", "排序" }, {"David", "戴维"}, {"leave", "离开"} };

for (auto& e : m1)
{
	cout << e.first << ": " << e.second << endl;
}

cout << endl;
for (auto& e : m2)
{
	cout << e.first << ": " << e.second << endl;
}

在这里插入图片描述

count

在这里插入图片描述
根据key统计它在容器中出现的次数,主要用于multimap中,因为map中不允许出现相同key的数据,对于multimap允许出现同key的数据,即使value也是相同的

map<string, string> m1{ {"David", "戴维"}, { "hello", "你好" }, {"leave", "离开"}, { "sort", "排序" },{"David", "戴维"}, { "hello", "你好" }, {"leave", "离开"}, { "sort", "排序" } };

multimap<string, string> m2{ {"David", "戴维"}, { "hello", "你好" }, {"leave", "离开"}, { "sort", "排序" },{"David", "戴维"}, { "hello", "你好" }, {"leave", "离开"}, { "sort", "排序" } };
cout << m1.count("David") << endl;//1
cout << m2.count("David") << endl;//2
m2.insert({ "David", "阿伟" });
cout << m2.count("David") << endl;//3

equal_range

在这里插入图片描述
在这里插入图片描述
用于返回一个多个相同key在容器中的区间,这个函数也是主要用于multimap中,对于map某一个key在这个容器中最多只会出现一次因此用处不大
返回值是一个pair对象,first指向该key值在容器中第一次出现的位置指向的仍是一个pair对象,second指向该key值在容器中最后一次出现位置的下一个位置,如果没有该key值,则返回的是一个不存在的区间
下面的it1.first在这里指向的仍是一个pair对象

map<string, string> m1{ {"David", "戴维"}, { "hello", "你好" }, {"leave", "离开"}, { "sort", "排序" }};

multimap<string, string> m2{ {"David", "戴维"}, { "hello", "你好" }, {"leave", "离开"}, { "sort", "排序" },
{"David", "戴维"}, { "hello", "你好" }, {"leave", "离开"}, { "sort", "排序" }, {"David", "戴维"}};

pair<map<string, string>::iterator, map<string, string>::iterator> it1 =  m1.equal_range("David");
pair<multimap<string, string>::iterator, multimap<string, string>::iterator> it2 = m2.equal_range("David");
cout << it1.first->first << " " << it1.second->first << endl;
//等价于(*it1.first).second
cout << it2.first->first << " " << it2.second->first << endl;

m2.erase(it2.first, it2.second);

for (auto& e : m2)
{
	cout << e.first << ": " << e.second << endl;
}

  • 31
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦想很美

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值