C++学习笔记(7)——标准模板库STL之set和map
零、pair类模板
pair与python中字典的键值对非常像。在C++中,pair的定义是:
1 | template <typename T1, typename T2> |
可以不写参数:pair<string, double> p
可以写参数(常用):pair<string, double> p1("xiaoming", 78)
可以这样初始化:pair<string, double> p2(pair<string, double>("xiaoming", 78)),当这样写的时候,其实是用了定义中的函数模板,参数必须是pair模板类对象的引用。
也可以这样初始化:pair<string, double> p3 = make_pair("xiaoming", 78)
访问pair对象的“键”(Key):p.first
访问pair对象的“值”(Value):p.second
一、multiset和set
C++的set类似于python中的集合。只不过,python的集合中的元素都是不能重复的。
使用multiset必须包含头文件set。mutilset类模板是这样定义的:
1 | template <typename Key, typename Pred=less<Key>, typename B=allocator<Key>> |
第一个参数:说明元素类型。
第二个参数:说明排序规则,实例化后的Pred可以是函数对象类,也可以是函数指针,这里默认的是less函数对象,定义如下:
1 | template <typename T> |
事实上在STL中自带一些函数对象类模板,less是其中一个。STL中自带的函数对象类模板,可以书上查,可以网上查,这里不一一列举。
第三个参数极少用到,不写。
定义一个multiset容器对象:multiset <int> a;,等价于multiset <int, less<int>, allocator<int>> a;
下面来看看我是怎么用的:
1 |
|
注意,容器内的类型若是类,那么许多符号需要进行重载:<<、<、>、==、······等等。
multiset自带的成员函数与vector和list很多重合,但是还有一些自己独有的,这里列举一下几个常用的:
m.insert(n); //将n插入容器中,返回其迭代器。
m.find(first, last, n); //在容器[first, last)查找n,找到返回其迭代器,找不到返回last的迭代器。first和last可以省略
m.erase(i); //删除i指向的元素,并返回后面一个元素的迭代器
m.erase(first, end); //删除区间[first, end),并返回迭代器last
m1.count(n); // 统计多少个元素的值与n相等
m.lower_bound(n); //查找一个最大位置it,使得[begin,it)中所有元素的关键字都比n小,返回值是迭代器
m.upper_bound(n); //查找一个最小位置it,使得[it, end)中所有元素的关键字都比n大,返回值是迭代器
m.equal_range(n); //同时求lower_bound和upper_bound,返回的是一个pair模板类对象x,x.first和x.second都是迭代器类型,前者是lower_bound,后者是upper_bound
注意,multiset和set中的find和count不是用“==”来比较相等的,而是遵循这样的原则:如果“x比y小”且“y比x小”同时为假,就认为x和y相等。
4.关于set
set和multiset类似,但是set不能有重复的元素。由于不能重复元素,所以set的insert函数与multiset的不同:
m.insert(n); //将n插入容器中,返回pair模板类对象x,若x.second=true,则说明插入成功,x.first=被插入元素的迭代器;若x.second=false,则说明已有该元素,x.first=已有元素的迭代器。
二、multimap和map
C++的map类似于python中的字典。
1.定义
使用multiset必须包含头文件set。mutilset类模板是这样定义的:
1 | template <typename Key, typename T, typename Pred=less<Key>, typename B=allocator<Key>> |
第一、二个参数:说明元素类型。
第三个参数:说明排序规则,实例化后的Pred可以是函数对象类,也可以是函数指针。这里默认的是less函数对象。
2.实例
注意一个问题:输出map的时候,需要重载<<,这是因为,map的元素是pair对象,如果不进行重载<<,那么编译将出错。
1 |
|
输出结果:
1 | a: 1 |
3.常用成员函数
与set中的成员函数是一样的,这里不再阐述。不过insert中的参数必须是pair模板类对象。例如上面的程序。
注意,multimap和map中的find和count不是用“==”来比较相等的,而是遵循这样的原则:如果“x比y小”且“y比x小”同时为假,就认为x和y相等。
4.关于map
set和multiset类似,但是set不能有重复的元素。
除了multimap的所有特点,map还有成员函数:T &operator[] (Key k)。例如上面的程序中,cout<<m['e']<<endl;将输出5,注意,这个方框里的是关键字(key)。
与set类似,map的insert函数也有这样的特性:
m.insert(n); //将n插入容器中,返回pair模板类对象x,若x.second=true,则说明插入成功,x.first=被插入元素的迭代器;若x.second=false,则说明已有该元素,x.first=已有元素的迭代器。



