C++STL(Standard Library)提供了一系列基于模板的容器,实现了各种经典数据结构,在容器中提供了迭代器作为容器的访问接口。

1 迭代器的类型

  迭代器是STL中提供的对容器元素的访问方式,可以简单地将迭代器看成指向容器中元素的指针,针对不同容器提供不同类型的迭代器来控制对容器元素的访问方式,迭代器有以下几种类型:

随机访问迭代器(Random-access Iterator):提供了最自由的操作,以及输入输出操作。

提供++--+-+=-=[]等操作。

双向迭代器(Bidirectional Iterator):提供了单步向前或向后操作,以及输入输出操作。

提供++--=*等操作。

前向迭代器(Forward Iterator):提供单向递增操作,以及输入输出操作。

提供++=*等操作。

输出迭代器(Output Iterator):提供单向递增、写入操作。

提供++=等操作。

输入迭代器(Input Iterator):提供单向递增、访问操作。

提供++*等操作。

2 容器的类型

序列容器(支持随机访问迭代器)
array——定长数组,提供一种STL方式来创建固定长度数组。

可以看成对之前版本中使用[]创建的数组的一种替代方式。

vector——动态数组,长度可以动态自动增长的顺序序列。

优势:支持快速访问元素、序列尾部的快速插入删除元素。

deque——双端序列,在头尾都可以进行快速操作的序列。

优势:支持头尾两端的快速插入删除元素,访问元素比vector稍慢一些,在大数据量的容量动态增减方面比vector有优势。

链表容器(支持前向或双向迭代器)
forward_list——单向链表,链表中的节点只能向后搜索,支持前向迭代器。
list——双向链表,链表中的节点可以向前和向后搜索,支持双向迭代器。

优势:链表支持在任意位置快速插入删除元素。

容器适配器(不支持迭代器)
stack——栈,先进后出(LIFO,Last In First Out)。
queue——队列,先进先出(FIFO,First In First Out)。
priority_queue——优先序列,内部维护了一个堆数据结构,堆顶为极值。

有序关联容器(支持双向迭代器)
set——有序集合,只包含不重复元素的有序集合。
multiset——有序多重集合,可以包含重复元素的有序集合。
map——有序映射,“键-值”对的有序集合,只包含不重复的键。
multimap——有序多重映射,”键-值“对的有序集合,可以包含重复的键。

优势:内部有序、支持快速查找。

无序关联容器(支持前向迭代器)
unordered_set——无序集合,只包含不重复元素的无序集合。
unordered_multiset——无序多重集合,可以包含重复元素的无序集合。
unordered_map——无序映射,“键-值”对的无序集合,只包含不重复的键。
unordered_multimap——无序多重映射,”键-值“对的无序集合,可以包含重复的键。

优势:支持快速查找。(查找速度比有序关联容器更快)

2.1 序列容器

2.1.1 定长数组 array c++11

位于命名空间std下,定义于头文件<vector>,内部元素按照内存地址顺序连续存放。
优势:访问O(1)、修改O(1)

迭代器
begin() 返回指向容器第一个元素的迭代器,++操作向end()方向靠近。
end() 返回指向容器最后一个元素的下一个位置的迭代器。
rbegin() 返回指向容器最后一个元素的迭代器,++操作向rend()方向靠近。
rend() 返回指向容器第一个元素的上一个位置的迭代器。
cbegin()、cend()与crbegin()、crend() 上述迭代器的const版本。

容量
empty() 判断是否为空。
size() 容器使用量的大小。

访问
operator[] 获取具体元素的引用,越界行为不确定。
at() 获取具体元素的引用,有边界检查可抛出异常。
front() 获取首部元素的引用。
back() 获取尾部元素的引用。
data() 获取底层数组的头指针,可以用来进行指针操作。

修改
fill(value) 使用固定值填满整个数组。
swap(vec) 交换两个容器内容,包括使用量和容量。

2.1.2 动态数组 vector

位于命名空间std下,定义于头文件<vector>,内部元素按照内存地址顺序连续存放。
优势:访问O(1)、修改O(1)、尾部位置插入O(1)
劣势:非尾部位置插入O(n)

迭代器
begin() 返回指向容器第一个元素的迭代器,++操作向end()方向靠近。
end() 返回指向容器最后一个元素的下一个位置的迭代器。
rbegin() 返回指向容器最后一个元素的迭代器,++操作向rend()方向靠近。
rend() 返回指向容器第一个元素的上一个位置的迭代器。
cbegin()、cend()与crbegin()、crend() 上述迭代器的const版本。c++11

rbegin()和back()有区别,一个是返回迭代器,一个是元素引用

容量
empty() 判断是否为空。
size() 容器使用量的大小。
resize() 重新分配使用量大小,使容器使用量变为n,直接影响size(),扩容超容量才会影响capacity()。
capacity() 容器容量的大小,包含空位。
reserve() 重新分配容量大小,只有扩容的时候有效,任何情况不影响容器size()。
shrink_to_fit() 让容量收缩至使用量的大小。c++11

访问
operator[] 获取具体元素的引用,越界行为不确定。
at() 获取具体元素的引用,有边界检查可抛出异常。
front() 获取首部元素的引用。
back() 获取尾部元素的引用。
data() 获取底层数组的头指针,可以用来进行指针操作。c++11

修改
assign(n, value) 对容器赋值,只有当n大于容量时会重新分配容量。
push_back()、pop_back() 尾部的插入和弹出。
insert(it, value) 在迭代器指向的位置位置插入元素。
erase(it) 在迭代器指向的位置删除单个元素或范围内多个元素。
swap(vec) 交换两个容器内容,包括使用量和容量。
clear() 清空容器的使用量,不影响容量,彻底vector可以使用。vector<int>().swap(myvector)
emplace(it, args…) 在迭代器指向的位置构建并插入,对象由args实时构造。c++11
emplace_back(args…) 在尾部位置构建并插入,对象由args实时构造。c++11

2.1.3 双端队列 deque

位于命名空间std下,定义于头文件<deque>,内部元素在内存地址上不能保证是完全连续的,而是由多个储存块组成。
优势:访问O(1)、修改O(1)、首尾位置插入删除O(1)
劣势:非首尾位置插入删除O(n)

迭代器
begin() 返回指向容器第一个元素的迭代器,++操作向end()方向靠近
end() 返回指向容器最后一个元素的下一个位置的迭代器
rbegin() 返回指向容器最后一个元素的迭代器,++操作向rend()方向靠近
rend() 返回指向容器第一个元素的上一个位置的迭代器
cbegin()、cend()与crbegin()、crend() 上述迭代器的const版本c++11

容量
empty() 判断是否为空。
size() 容器大小。
resize() 重新分配容器大小。
shrink_to_fit() 收缩多余的内存占用至size(),为支持动态扩容,deque实际内存分配可能比size()大。c++11

访问
operator[] 获取具体元素的引用,越界行为不确定。
at() 获取具体元素的引用,有边界检查可抛出异常。
front() 获取首部元素的引用。
back() 获取尾部元素的引用。

修改
assign(n, value) 对容器赋值。

push_back() 在尾部位置插入元素。
push_front() 在首部位置插入元素。
pop_back() 在尾部位置删除元素。
pop_front() 在首部位置删除元素。

insert(it, value) 根据迭代器位置位置插入元素。
erase(it) 根据迭代器位置删除单个元素或范围内多个元素。
swap(deque) 交换两个容器内容,包括使用量和容量。
clear() 清空容器。
emplace(it, args…) 在迭代器指向的位置构建并插入,对象由args实时构造。c++11
emplace_front(args…) 在首部位置构建并插入,对象由args实时构造。c++11
emplace_back(args…) 在尾部位置构建并插入,对象由args实时构造。c++11

2.2 链表容器

2.2.1 双向链表 list

位于命名空间std下,定义于头文件<list>,内部元素按照双向链表的形式存放,每个元素都有分别指向前、后元素的两个指针。
优势:插入、删除耗时O(1)
劣势:查找O(n)

迭代器
begin() 返回指向容器第一个元素的迭代器,++操作向end()方向靠近。
end() 返回指向容器最后一个元素的下一个位置的迭代器。
rbegin() 返回指向容器最后一个元素的迭代器,++操作向rend()方向靠近。
rend() 返回指向容器第一个元素的上一个位置的迭代器。
cbegin()、cend()与crbegin()、crend() 上述迭代器的const版本。c++11

容量
empty() 判断是否为空。
size() 容器大小。
resize() 重新分配容器大小。

访问
front() 获取首元素的引用。
back() 获取尾元素的引用。

修改
assign(n, value) 对容器赋值。

emplace_front(args…) 在首部构建并插入,对象由args实时构造。c++11
push_front() 在首部插入元素。
pop_front() 在首部删除元素。

emplace_back() 在尾部构建并插入,对象由args实时构造。c++11
push_back() 在尾部插入元素。
pop_back() 在尾部删除元素。

empalce(it, args…) 在迭代器指向的位置构建并插入。c++11
insert(it, value) 在迭代器指向的位置位置插入元素。
erase(it) 在迭代器指向的位置删除单个元素或范围内多个元素。
swap(list) 交换两个容器内容。
clear() 清空容器。

操作
splice(it, list, pos) 将另一个链表list中的元素链入(从list中移走)当前it迭代器的位置,list可以是自身,用于将移动自身的某一段。

std::list<int> mylist1, mylist2;
std::list<int>::iterator it;

// set some initial values:
for (int i=1; i<=4; ++i){mylist1.push_back(i);}      // mylist1: 1 2 3 4
for (int i=1; i<=3; ++i){mylist2.push_back(i*10);}   // mylist2: 10 20 30

it = mylist1.begin();
++it;                            // points to 2

// mylist1将mylist2全部链入自身
mylist1.splice (it, mylist2);   // mylist1: 1 10 20 30 2 3 4
                                // mylist2 (empty)
                                // "it" still points to 2 (the 5th element)

// mylist2将mylist1中的单个元素链入自身
mylist2.splice (mylist2.begin(),mylist1, it);   // mylist1: 1 10 20 30 3 4
                                                // mylist2: 2
                                                // "it" is now invalid.

// 旋转自身,mylist1将自身的某一段移至首部
it = mylist1.begin();
std::advance(it,3);           // "it" points now to 30
mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());  // mylist1: 30 3 4 1 10 20

remove() 删除容器中所有指定值的元素。
remove_if(Predicate) 删除满足断言的所有元素,对每个元素会调用pred(*i)

// a predicate implemented as a function:
bool single_digit (const int& value) { return (value<10); }
// a predicate implemented as a class:
struct is_odd {
  bool operator() (const int& value) { return (value%2)==1; }
};
……
int myints[]= {15,36,7,17,20,39,4,1};
list<int> mylist (myints,myints+8);     // 15 36 7 17 20 39 4 1
mylist.remove_if (single_digit);        // 15 36 17 20 39
mylist.remove_if (is_odd());            // 36 20

unique() 去除相邻的重复元素,只保留第一个,如果重复元素不相邻,则不会去除。(一般预先做一次排序)
merge(list) 将list有序链入(list最后为空)链表。(要想结果有序,需要两个链表预先都有序)
sort() 对链表稳定排序。
reverse() 翻转整个链表。

merge()和sort()默认使用less比较函数,可以在参数中指定greater<typename>,进行从大到小的排序。

2.2.2 单向链表 forward_list c++11

位于命名空间std下,定义于头文件<forward_list>,内部元素按照单向链表的形式存放,每个元素都有指向后一个元素的指针。
优势:插入O(1)、删除O(1)
劣势:查找O(n)

迭代器
befor_begin() 返回指向第一个元素的上一个位置的迭代器,++操作向end()方向靠近。
begin() 返回指向容器第一个元素的迭代器,++操作向end()方向靠近。
end() 返回指向容器最后一个元素的下一个位置的迭代器。
cbegin()、cend()、cbefore_begin() 上述迭代器的const版本。

容量
empty() 判断是否为空。
size() 容器大小。
resize() 重新分配容器大小。

访问
front() 获取首元素的引用。

修改
assign(n, value) 对容器赋值。

emplace_front(args…) 在首部构建并插入,对象由args实时构造。
push_front() 在首部插入元素。
pop_front() 在首部删除元素。

emplace_after() 在迭代器指向的位置之后构建并插入,对象由args实时构造。
insert_after() 在迭代器指向的位置之后插入元素。
erase_after() 在迭代器指向的位置之后删除元素。

swap(forward_list) 交换两个容器内容。
clear() 清空容器。

操作
splice_after(it, list, pos) 将链表list中的元素链入(从list中移走)当前it迭代器的位置之后,ist可以是自身,用于将移动自身的某一段。
remove() 删除容器中所有指定值的元素。
remove_if(Predicate) 删除满足断言的所有元素,对每个元素会调用pred(*i)
unique() 去除相邻的重复元素,只保留第一个,如果重复元素不相邻,则不会去除。(一般预先做一次排序)
merge(forward_list) 将list有序链入(list最后为空)链表。(要想结果有序,需要两个链表预先都有序)
sort() 对链表稳定排序。
reverse() 翻转整个链表。

merge()和sort()默认使用less比较函数,可以在参数中指定greater<typename>,进行从大到小的排序。

2.3 适配器容器

  适配器容器是对容器的再次封装,底层可能是序列容器或者链表。适配器容器的作用是为了提供在具体场景下能够使用的专用数据结构。

2.3.1 栈 stack

位于命名空间std下,定义于头文件<stack>,内部元素按照后进先出(LIFO)的规则运行。
在栈数据结构中,访问、插入、删除都只能对栈顶进行,耗时都为O(1),常用于深度优先搜索以及递归中使用。

stack是对容器的一种包装,默认的底层容器是deque,也可以换成vector、list等,只要支持empty、size、back、push_back、pop_back五项操作即可。

容量
empty() 判断是否为空
size() 容器大小

访问
top() 获取栈顶元素的引用

修改
push() 入栈。
pop() 出栈。
swap(stack) 交换两个容器内容,调用的是底层包装的数据结构的swap操作。c++11
emplace(args…) 入栈,对象由args实时构造,而push入栈已构造完成的对象。c++11

2.3.2 队列 queue

位于命名空间std下,定义于头文件<queue>,内部元素按照先进先出(FIFO)的规则运行。
在队列数据结构中,访问可以对队列的头部和尾部进行,插入是对队列尾部(入队),删除是对队列首部(出队),耗时都为O(1),常用于宽度优先搜索中使用。

queue是对容器的一种包装,默认的底层容器是deque,也可以换成list等,只要支持empty、size、front、back、push_back、pop_front六项操作即可。

容量
empty() 判断是否为空
size() 容器大小

访问
front() 获取队列首部元素的引用
back() 获取队列尾部元素的引用

修改
push() 入队
pop() 出队
swap(queue) 交换两个容器内容,调用的是底层包装的数据结构的swap操作。c++11
emplace(args…) 入队,对象由args实时构造,而push入队已构造完成的对象。c++11

2.3.3 优先序列 priority_queue

位于命名空间std下,定义于头文件<queue>,内部元素按照有序堆(大顶堆、小顶堆)进行存放。因为需要实时维护堆的有序性,插入、删除、修改操作耗时O(log n)。

容量
empty() 判断是否为空。
size() 容器大小。

访问
top() 获取堆顶元素。

修改
push() 向堆中压入元素。
emplace() 构建并压入元素。
pop() 删除堆顶元素。

2.3.3.1 构造小顶堆

模版类priority_queue的定义如下:

template<
    class T,
    class Container = std::vector<T>,
    class Compare = std::less<typename Container::value_type>
> class priority_queue;

默认构造的优先序列为大顶堆优先序列,因为模版定义中使用的默认比较函数是less,要构造小顶堆优先序列,对于已经内置了比较函数的系统数据类型,可以直接使用内置的比较函数std::greater<typename>

priority_queue<int> myPriorityQueue; // 默认大顶堆优先序列
priority_queue<int, vector<int>, greater<int>> myPriorityQueue; // 小顶堆优先序列
2.3.3.2 使用自定义类型作为基础类型

对自定义类型构建优先序列,需要手动添加比较函数,假设自定义类型如下:

class ListNode {
public:
    int val;
    ListNode *next;
    ListNode(int val) {
       this->val = val;
       this->next = NULL;
    }
};

我们为ListNode *这个类型定义大顶堆优先序列,有以下几种方式:

使用结构、或者类来重载()运算符的方式:

struct Cmp{
    bool operator() (ListNode *& left, ListNode *& right){return left->val > right->val;}
}myCmp;
priority_queue<ListNode *, vector<ListNode *>, cmp> myPriorityQueue; // 使用类名
priority_queue<ListNode *, vector<ListNode *>, decltype(mycmp)> myPriorityQueue; // 也可以使用类的声明对象

定义Cmp类(可以用struct或者class),声明myCmp对象;
如果类定义使用class,该运算符重栽的访问限定符必须为public;
priority_queue模版的第三个位置需要的是类型信息,decltype()函数用于获取表达式的数据类型。

使用比较函数的方式:

bool cmp (ListNode *& left, ListNode *& right){return left->val > right->val;}
priority_queue<ListNode *, vector<ListNode *>, decltype(&cmp)> myPriorityQueue(cmp);

定义比较函数,&cmp为函数指针,用decltype()函数获取函数指针的类型;
还需要多一个步骤,优先序列初始化时传入该比较函数的地址,函数名即为函数地址

使用Lamda表达式的方式:

function<bool(ListNode *&, ListNode *&)> cmp = [](ListNode *& left, ListNode *& right){return left->val > right->val;};
priority_queue<ListNode *, vector<ListNode *>, decltype(cmp)> myPriorityQueue(cmp);

定义lamda表达式,用function包装的cmp为指向该lamda表达式的函数指针,用decltype()函数取指针类型
优先序列初始化时传入该比较函数的地址,直接传入该cmp指针

auto cmp=[](ListNode *& left, ListNode *& right){return left->val > right->val;};
priority_queue<ListNode *, vector<ListNode *>, decltype(comp)> myPriorityQueue(cmp);

用auto代替实际类型,可以简化定义的过程。最后说明一下,比较函数中使用>大于号定义的是小端堆优先序列,不要记反。

2.4 有序关联容器(底层:红黑树)

2.4.1 集合 set/multiset

位于命名空间std下,定义于头文件<set>,内部元素按照红黑树(平衡二叉查找树)有序存放。
set的元素不允许重复,multiset的元素可以重复,元素为const不允许直接更改。
优势:查找O(log n)
劣势:插入O(log n)、删除O(log n)

迭代器
begin() 返回指向容器第一个元素的迭代器,++操作向end()方向靠近。
end() 返回指向容器最后一个元素的下一个位置的迭代器。
rbegin() 返回指向容器最后一个元素的迭代器,++操作向rend()方向靠近。
rend() 返回指向容器第一个元素的上一个位置的迭代器。
cbegin()、cend()与crbegin()、crend() 上述迭代器的const版本。c++11

容量
empty() 判断是否为空。
size() 容器的大小,set容器因为内部维护的是一棵红黑树所以使用量即是容量。

修改
insert(value) 插入元素,返回pair,first代表值,second代表是否插入成功。
erase() 删除元素,可以用值或者迭代器作参数,用值时返回删除的元素个数。
swap(set) 交换两个容器内容,还有全局版本的std::swap(set1, set2)。
clear() 清空容器
emplace(args…) 插入,对象由args实时构造,而insert插入已构造完成的对象。c++11

操作
find(value) 返回指向查询到的第一个匹配元素的迭代器,未找到则返回set::end()/multiset::end()。
count(value) 计算元素个数。
lower_bound(value) 返回指向>=value的第一个元素的迭代器。
upper_bound(value) 返回指向>value的第一个元素的迭代器。
equal_range(value) 返回包含两个迭代器的pair,迭代器分别指向lower_boundupper_bound

2.4.2 映射 map/multimap

位于命名空间std下,定义于头文件<map>,内部元素按照红黑树(平衡二叉查找树)有序存放。
每一个元素都有key值和value值,key值用于排序,map中的key不允许重复,multimap的key可以重复,value用于储存实际数据,它们的类型可以不相同,组成一个pair类型的数据结构pair<const key, value>作为map的元素。查找、插入、修改、删除耗时都为O(log n)。

map容器内部的key_comp用来比较key的大小,以此来排序。对于multimap相同key值的元素并没有进行排序。
容器也提供内部函数value_comp用来比较pair<key, value>的大小。

迭代器
begin() 返回指向容器第一个元素的迭代器,++操作向end()方向靠近。
end() 返回指向容器最后一个元素的下一个位置的迭代器。
rbegin() 返回指向容器最后一个元素的迭代器,++操作向rend()方向靠近。
rend() 返回指向容器第一个元素的上一个位置的迭代器。
cbegin()、cend()与crbegin()、crend() 上述迭代器的const版本。c++11

容量
empty() 判断是否为空。
size() 容器大小。

访问(multimap不提供)
operator[] 获取具体元素的引用,越界行为不确定。
at() 获取具体元素的引用,有边界检查可抛出异常。c++11

multimap不提供[]和at来对元素访问,更多的是通过lower_bound、upper_bound、equal_range来访问对应的元素范围。

修改
insert() 插入元素

insert(pair<int, int>(1, 100));
insert(make_pair(2, 200));
insert({2, 200});

erase() 删除元素,可以用值或者迭代器作参数,用值时返回删除的元素个数。
swap(map) 交换两个容器内容,包括使用量和容量。
clear() 清空容器。
emplace(args…) 构建并插入元素,对象由args实时构造。c++11

操作
find(pair) 返回指向查询到的第一个匹配元素的迭代器,未找到则返回map::end()/multimap::end()。
count(pair) 计算元素个数。
lower_bound(pair) 返回指向>=key的第一个元素的迭代器。
upper_bound(pair) 返回指向>key的第一个元素的迭代器。
equal_range(pair) 返回包含两个迭代器的pair,迭代器分别指向lower_boundupper_bound

2.5 无序关联容器(底层:哈希表)

2.5.1 无序集合 unordered_set/unordered_multiset c++11

位于命名空间std下,定义于头文件<unordered_set>,内部元素按照哈希表存放。
set的元素不允许重复,multiset的元素可以重复,元素为const不允许直接更改,元素内部无序。查找、插入、删除耗时都为O(1),空间复杂度高,一般比数据量大一个数量级。

迭代器
begin() 返回指向容器第一个元素的迭代器,++操作向end()方向靠近。
end() 返回指向容器最后一个元素的下一个位置的迭代器。
cbegin()、cend() 上述迭代器的const版本。c++11

容量
empty() 判断是否为空。
size() 容器大小。

查找
find(value) 查找元素是否存在。
count(value) 计算元素个数。
equal_range(value) 返回包含两个迭代器的pair,迭代器分别指向>=value的第一个元素与>value的第一个元素。

修改
insert(value) 插入元素,返回pair,first代表值,second代表是否插入成功。
erase() 删除元素,可以用值或者迭代器作参数,用值时返回删除的元素个数。
swap(set) 交换两个容器内容,还有全局版本的std::swap(set1, set2)。
clear() 清空容器
emplace(args…) 插入,对象由args实时构造,而insert插入已构造完成的对象。c++11

哈希桶
bucket_count() 哈希表中桶的数量。
bucket_size(n) 哈希表中第n个桶中包含的元素数量。
bucket(value) 返回包含当前元素的桶序号。

2.5.2 无序映射 unordered_map/unordered_multimap c++11

位于命名空间std下,定义于头文件<unordered_map>,内部元素按照哈希表存放。
每一个元素都有key值和value值,key值用于排序,map中的key不允许重复,multimap的key可以重复,value用于储存实际数据,它们的类型可以不相同,组成一个pair类型的数据结构pair<const key, value>作为map的元素。查找、插入、修改、删除耗时都为O(1),空间复杂度高,一般比数据量大一个数量级

迭代器
begin() 返回指向容器第一个元素的迭代器,++操作向end()方向靠近。
end() 返回指向容器最后一个元素的下一个位置的迭代器。
cbegin()、cend() 上述迭代器的const版本。c++11

容量
empty() 判断是否为空。
size() 容器大小。

访问(unordered_multimap不提供)
operator[] 获取具体元素的引用,越界行为不确定。
at() 获取具体元素的引用,有边界检查可抛出异常。c++11

multimap不提供[]和at来对元素访问,更多的是通过equal_range来访问对应的元素范围。

修改
insert() 插入元素

insert(pair<int, int>(1, 100));
insert(make_pair(2, 200));
insert({2, 200});

erase() 删除元素,可以用值或者迭代器作参数,用值时返回删除的元素个数。
swap(map) 交换两个容器内容,包括使用量和容量。
clear() 清空容器。
emplace(args…) 构建并插入元素,对象由args实时构造。c++11

哈希桶
bucket_count() 哈希表中桶的数量。
bucket_size(n) 哈希表中第n个桶中包含的元素数量。
bucket(value) 返回包含当前元素的桶序号。

操作
find(pair) 返回指向查询到的第一个匹配元素的迭代器,未找到则返回map::end()/multimap::end()。
count(pair) 计算元素个数。
equal_range(pair) 返回包含两个迭代器的pair,迭代器分别指向>=value的第一个元素与>value的第一个元素。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐