(C++)map、set的介绍和使用

个人主页:Lei宝啊 

愿所有美好如期而遇


目录

前言:

set

set的构造

set的迭代器

set方法

insert

erase

count

lower_bound && upper_bound

multiset

map

map的构造

map的迭代器

map方法

insert

[]运算符重载

multimap


前言:

SGI-STL中关于键值对的定义:

template <class T1, class T2>
struct pair
{
    typedef T1 first_type;
    typedef T2 second_type;

    T1 first;
    T2 second;

    pair(): first(T1()), second(T2())
    {}

    pair(const T1& a, const T2& b)
        : first(a)
        , second(b)
    {}
};

typedef pair<const key, T> value_type;  

先对pair了解一下,后面我们会用到。 

同时要提到的是,接下来我们要介绍的四个关联性容器底层都是红黑树,即平衡搜索树,容器中的元素是一个有序的序列。

set

我们使用set时,只需要插入value一个值,但实际上底层是<value,value>构成的键值对。

set中元素不会重复,所以他具有去重功能。

set中元素不可修改(为了保证不破坏set元素的有序性),但是可以插入一个新元素或者删除元素。

set在进行遍历时默认是中序遍历,同时排列方式默认是less,也就是升序排列。 

set的构造

第一种是构造一个空的set 

第二个是用(first,last) 区间的元素进行构造

第三个是拷贝构造

set的迭代器

前两个是普通迭代器,加上r表示反向迭代器,加上c表示const迭代器。

这里我们简单介绍使用set的普通迭代器,他的原理及反向迭代器我们在这里说过:迭代器理解及模拟icon-default.png?t=N7T8https://blog.csdn.net/m0_74824254/article/details/135838211?spm=1001.2014.3001.5501

#include <iostream>
#include <set>
using namespace std;

int main()
{
	int array[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0, 1, 3, 5, 7, 9, 2, 4,6, 8, 0 };
	set<int> st(array, array + sizeof(array) / sizeof(array[0]));

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

	return 0;
}

set方法

insert

pair<iterator,bool> insert (const value_type& val)

insert返回值为pair<iterator,bool>类型,我们试着使用一下:

	pair<set<int>::iterator, bool> p = st.insert(100);
	cout << *(p.first) << " " << p.second << endl;

p.first得到st中指向100的迭代器,解引用得到100这个值,p.second得到bool值,这个值表征插入是否成功。

分两种情况:

  • 没有这个值,插入成功,返回这个值的迭代器,bool值为true
  • 有这个值,插入失败 ,返回这个值的迭代器,bool值为false
erase
	st.erase(100);

	set<int>::iterator it2 = st.find(1);
	st.erase(it2);

count

返回set中值为x的元素的个数,实际上在set中这个方法用途就是判断元素在不在,在就是1,不在就是0。

lower_bound && upper_bound
iterator lower_bound (const value_type& val) const;

返回大于等于x的值的位置

iterator upper_bound (const value_type& val) const;

返回大于x的值的位置  

我们结合两者一起来看:

删除了[1,6)范围内的值,右边界要大于5,set中大于5的最近的值为6。

 

multiset

与set不同的是insert返回值不同,同时multiset允许插入相同的值,无法去重。

我们简单使用一下:

 

map

键值对<key,T>,Compare比较时根据key进行比较,和T没有关系

map支持[]运算符重载,在[]中填入key,就可以找到对应的值。

map中的key唯一,不可修改。

map的构造

同set,不解释。

map的迭代器

也是同set

map方法

insert
typedef pair<const key, T> value_type; 这个我们前面写到过。

#include <iostream>
#include <string>
#include <map>
using namespace std;

int main()
{
	map<string, string> m;

	m.insert(pair<string, string>("apple", "苹果"));
	m.insert(make_pair("banana", "香蕉"));
	m.insert({ "fruit","水果" });

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

	return 0;
}

[]运算符重载
mapped_type& operator[] (const key_type& k);

key_type就是key,mapped_type就是T(value),也就是说可以通过key去寻找到value,同时,如果这个key不存在,则创建一个key,value如果没有,则采取默认值。

#include <iostream>
#include <string>
#include <map>
using namespace std;

int main()
{

	string s[] = { "香蕉" ,"苹果","葡萄" };
	map<string, int> m;

	for (auto& e : s)
	{
		m[e]++;
	}

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

	return 0;
}

我们尝试探究一下operator[]的实现原理:

(*((this->insert(make_pair(k,mapped_type()))).first)).second 

首先make_pair就是构造一个pair<k,mapped_type>类型的对象,然后将他插入this指向的map对象中,insert返回值是pair<iterator,bool>,这里的迭代器理所当然就是map对象的迭代器(由map对象调用的insert方法),first也就取到了这个迭代器,这个迭代器的类型是pair*类型,指向pair<k,mapped_type>类型的对象,解引用取second就是得到value值,也就是operator[]返回值的引用。

multimap

这里允许插入相同key的键值对,其他类似于multiset。

  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Lei宝啊

觉得博主写的有用就鼓励一下吧

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

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

打赏作者

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

抵扣说明:

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

余额充值