Associative Container
set
¶
set
是关联容器,含有键值类型对象的已排序集,搜索、移除和插入拥有对数复杂度。 set
内部通常采用红黑树实现。
和数学中的集合相似, set
中不会出现值相同的元素。
插入与删除操作¶
insert(x)
当容器中没有等价元素的时候,将元素 x 插入到set
中。erase(x)
删除值为 x 的元素,返回删除元素的个数。erase(pos)
删除迭代器为 pos 的元素,要求迭代器必须合法。erase(first,last)
删除迭代器在[first,last) clear()
清空set
。
insert 函数的返回值
insert 函数的返回值类型为 pair<iterator, bool>
,其中 iterator 是一个指向所插入元素(或者是指向等于所插入值的原本就在容器中的元素)的迭代器,而 bool 则代表元素是否插入成功,由于 set
中的元素具有唯一性质,所以如果在 set
中已有等值元素,则插入会失败,返回 false,否则插入成功,返回 true; map
中的 insert 也是如此。
迭代器¶
set
提供了以下几种迭代器:
begin()/cbegin()
返回指向首元素的迭代器,其中*begin = front
。end()/cend()
返回指向数组尾端占位符的迭代器,注意是没有元素的。rbegin()/rcbegin()
返回指向逆向数组的首元素的逆向迭代器,可以理解为正向容器的末元素。rend()/rcend()
返回指向逆向数组末元素后一位置的迭代器,对应容器首的前一个位置,没有元素。
以上列出的迭代器中,含有字符 c
的为只读迭代器,你不能通过只读迭代器去修改 set
中的元素的值。如果一个 set
本身就是只读的,那么它的一般迭代器和只读迭代器完全等价。只读迭代器自 C++11 开始支持。
查找操作¶
count(x)
返回set
内键为 x 的元素数量。find(x)
在set
内存在键为 x 的元素时会返回该元素的迭代器,否则返回end()
。lower_bound(x)
返回指向首个不小于给定键的元素的迭代器。如果不存在这样的元素,返回end()
。upper_bound(x)
返回指向首个大于给定键的元素的迭代器。如果不存在这样的元素,返回end()
。empty()
返回容器是否为空。size()
返回容器内元素个数。
lower_bound
和 upper_bound
的时间复杂度
set
自带的 lower_bound
和 upper_bound
的时间复杂度为
但使用 algorithm
库中的 lower_bound
和 upper_bound
函数对 set
中的元素进行查询,时间复杂度为
multiset
¶
multiset
是关联容器,含有键值类型对象的已排序集,搜索、移除和插入拥有对数复杂度。
与 set
不同的是, multiset
允许不同元素间拥有相同的值。
插入与删除操作¶
insert(x)
将元素 x 插入到multiset
中。erase(x)
删除值为 x 的 所有 元素,返回删除元素的个数。erase(pos)
删除迭代器为 pos 的元素,要求迭代器必须合法。erase(first,last)
删除迭代器在[first,last) clear()
清空multiset
。
迭代器¶
multiset
的迭代器和 set
的 迭代器 类似,这里不再赘述。
查找操作¶
multiset
的查找操作和 set
的 查找操作 类似,这里不再赘述。
map
¶
map
是有序键值对(Attribute–value pair)容器,它的元素的键是唯一的。搜索、移除和插入操作拥有对数复杂度。 map
通常实现为红黑树。
你可能需要存储一些键值对,例如存储学生姓名对应的分数: Tom 0
, Bob 100
, Alan 100
。 但是由于数组下标只能为非负整数,所以无法用姓名作为下标来存储,这个时候最简单的办法就是使用 STL 中的 map
了!
map
重载了 operator[]
,可以用任意定义了 operator <
的类型作为下标(在 map
中叫做 key
,也就是索引):
map<Key, T> yourMap;
其中, Key
是键的类型, T
是值的类型,下面是使用 map
的实例:
map<string, int> mp;
添加元素¶
- 直接赋值,例如
mp["Tom"]=0
- 通过插入一个类型为
pair<Key, T>
的值,例如mp.insert(pair<string,int>("Alan",100));
- 使用
initializer_list
:
map<string, int> mp = {{"Tom", 0}, {"Bob", "100"}, {"Alan", 100}};
查找、修改元素¶
- 使用赋值语法:
int grade=mp["Tom"]
。 - 使用成员函数
iterator find( const Key& key );
来确定一个索引是否在map
中。它会返回指向该元素的迭代器;如果索引不在map
中,则会返回尾后迭代器mp.end()
。 - 如果你想获得
map
里全部的元素,请使用迭代器,解引用迭代器会得到一个类型为pair<Key, T>
的值:
for (iter = mp.begin(); iter != mp.end(); ++iter)
cout << iter->first << " " << iter->second << endl;
其中使用 mp.begin()
可以得到指向 map
首元素的迭代器。 如果使用 C++11(及以上),还可以使用 C++11 的范围 for 循环
for (auto &i : mp) {
printf("Key : %d, Value : %d\n", i.first, i.second);
}
使用迭代器遍历大小为 map
的时间复杂度是
删除元素¶
如果你想删除 Tom
这个元素,则可以利用 find
函数找到 Tom
,然后再 erase
如下
map<string, int>::iterator it;
it = mp.find("Tom");
mp.erase(it)
如果你想清空所有的元素,可以直接 mp.clear()
其他函数¶
count
返回匹配特定键的元素出现的次数,例如mp.count("Tom")
。swap
可以交换两个map
,例如swap(m1,m2)
。size
返回map
中元素的个数。empty
如果map
为空则返回true
,例如mp.empty()
。
multimap
¶
和 map
类似, multimap
是有序键值对容器,但允许多个元素拥有同一键。其搜索、插入操作拥有对数复杂度。删除单个元素在最坏情况下具有对数复杂度,均摊为常数复杂度。
Warning
正是因为 multimap 允许多个元素拥有同一键的特点,multimap 并没有提供给出键访问其对应值的方法。
插入与删除操作¶
- 通过向
multimap
中插入一个类型为pair<Key, T>
的值可以达到插入元素的目的,例如mp.insert(pair<string,int>("Alan",100));
; erase(x)
: 删除键为 x 的 所有 元素,返回删除元素的个数。erase(pos)
: 删除迭代器为 pos 的元素,要求迭代器必须合法。erase(first,last)
: 删除迭代器在[first,last) clear()
: 清空容器。
查找操作¶
count(x)
: 返回容器内键为 x 的元素数量。复杂度为O(\log(size)+ans) find(x)
: 若容器内存在键为 x 的元素,会返回该元素的迭代器(如果有多个键为 x 的元素会返回任意一个);否则返回end()
。lower_bound(x)
: 返回指向首个不小于给定键的元素的迭代器。upper_bound(x)
: 返回指向首个大于给定键的元素的迭代器。若容器内所有元素均小于或等于给定键,返回end()
。empty()
: 返回容器是否为空。size()
: 返回容器内元素个数。
buildLast update and/or translate time of this article,Check the history
editFound smelly bugs? Translation outdated? Wanna contribute with us? Edit this Page on Github
peopleContributor of this article OI-wiki
translateTranslator of this article Visit the original article!
copyrightThe article is available under CC BY-SA 4.0 & SATA ; additional terms may apply.