C++ primer阅读笔记---------------关联容器

来源:互联网 发布:java工程师职业规划 编辑:程序博客网 时间:2024/05/22 15:43

该博客用于记录自己在阅读过程中不懂的知识点,很少用到但比较重要的知识点以及模棱两可的知识点


关联容器按照map/set, 有序无序(unordered), 是否重复(multi)分为8种,分别是

map
set
multimap //可重复
multiset
unordered_map //无需,哈希
unordered_set
unordered_multimap
unordered_multiset

map通常称为关联数组,其下标不用是整数,下标是map的key类型,map[key]的值便是与key成对的value

可以将关联容器初始化为另一个关联容器的拷贝,也可以从一个值范围来初始化关联容器

关联容器的关键字必须定义元素比较的方法(比较操作类型,字面值类型和string类型都有默认的比较操作类型“<”)
multiset<myClass, decltype(myCmp)*> mySet(myCmp);
用myCmp来初始化mySet对象表示当我们向mySet添加元素时,通过调用myCmp来排序

关键字类型必须是严格弱序的,可以将其看成“小于等于”,且逻辑上遵守算术意义上的小于等于

pair标准库类型,当创建一个pair对象时,应该提供两个参数,参数可以是容器,通过.first和.second来访问pair的数据成员(public)
pair<string, vector<int>> line; line.first, line.second

make_pair(v1, v2) //返回一个pair,其类型由v1和v2推断出来

pair之间可以使用<, >, <=, >=, ==, !=先比第一个数据成员再比第二个数据成员

key_type //关键字类型
mapped_type //map中的值类型
value_type //容器中的元素类型

两关联容器的关键字都是const的

通常不对关联容器使用泛型算法,因为关键字是const的,实际上如果对关联容器使用泛型算法,通常将它当成一个源序列或着目的容器(copy, inserter)

当使用insert向map和set插入重复元素时,对容器没有任何效果

这里总结一下insert和emplace的区别:emplace是在容器中构造,insert是拷贝

添加单一的元素进set和map返回的是一个pair,包含一个指向该元素的迭代器,和一个插入是否成功的bool值
insert(v)/insert(args)
添加一个范围或值列表,返回void
insert(b, e)/insert(il)
添加一个对象到某个位置,返回指向插入对象的迭代器
insert(p, v)/insert(p, args)

c.erase(k) //删除关键字是k的对象,返回删除的数量
c.erase(p) //删除迭代器p所指对象,p必须是一个存在且可行的值,返 回一个指向删除元素后的元素的迭代器
c.erase(b, e) //返回e

不能对可重复的map进行下标操作,除了上面提到的类似数组的操作外,还有
c.at(k)

关联容器访问元素
c.find(k) //返回关键字为k的元素,若没有,返回尾后迭代器
c.count(k)
c.lower_bound(k) //返回关键字小于k的元素的迭代器
c.upper_bound(k)
c.equal_range(k) //返回关键字等于k的元素的范围,用一个pair存储, 如果不存在,pair的两个成员都是end()

有时维护有序容器的序的代价很高,此时,无序容器非常的有用
无序容器在存储上组织为一组桶, 每个桶保存1个或多个元素,容器使用哈希函数将元素映射到桶,也就是说,当访问一个元素时,先计算元素的哈希值,找到它所在的桶,无序容器的性能依赖于哈希函数的质量,桶的大小和数量,为了方便管理桶,无序容器提供了一组管理桶的函数:
c.bucket_count() //当前桶的数量
c.max_bucket_count()
c.bucket_size(n) //第n个桶多少元素
c.bucket(k) //k在哪个桶

local_iterator/const_local_iterator //访问桶中元素的迭代器类型
c.begin(n)/c.end(n)/c.cbegin(n)/c.cend(n) //第n个桶的首尾后迭代器
哈希策略
c.load_factor() //每个桶的平均元素数量
c.max_load_factor() //
c.rehash(n) //重新存储,使得bucket_count >=n同时大于容器中元素数量 / c.max_load_factor()
c.reserve(n) //重新存储使得c可以保存n个元素且不必rehash


标准库为内置类型(包括指针),string,智能指针类型提供了hash模板,所以我们可以直接定义以上类型的无序容器,但当我们使用自定义类类型的时候,我们必须提供自己的hash模板版本(如何做?挖坑)

原创粉丝点击