map, unordered_map, set, unordered_set

cplusplus.com说map的[]、at()、find()、insert()的时间复杂度都是O(logn),因为map是用二叉搜索树实现的(复杂度O(logn)~O(n),平均O(logn)),而我容易误认为是类似数组[]的O(1)。
unordered_map(库文件同名,按hash值组织进buckets)相比map在根据key获得mapped value更快(平均O(1)),但是在iterator上效率更低。
set和unordered_set同理。(实现方式同上)

注意,入参在map中时,[]与at()都是返回映射值的引用;而入参不在map中时,[]会新建成员,at()会抛出异常。

项目中,要不是严苛追求效率,可以尽可能借助STL,有利于降低代码复杂度,提高可维护性和可阅读性,降低出错率

成员

[], at, insert, emplace,find的复杂度
map, set平均O(logn),最差O(n)
unordered_map, unordered_set平均O(1),最差O(n)

insert

key不存在时才插入,不会覆盖已有成员。有多种语法,详见cplusplus.com
mp.insert(make_pair(a, b));

emplace

与insert一样,只有key不存在时才插入,只是用法更简单。
mymap.emplace(‘x’,100);//这里key是字符x

iterator

map有序,迭代器一直有效;而unordered_map是无序的,元素根据hash值被组织进buckets从而可更快通过key获得value(平均O(1),最差O(n)),由于可能因为size等变化而rehash,iterator不是一直有效的。
变量的声明map<char,int>::iterator it = mymap.begin();
begin()->first是key,begin()->second是mapped value。
begin()可以用来修改它指向的内容,但cbegin()不可以。crbegin()同理。
rbegin()返回指向尾元素的反向迭代器。是有必要的,因为end()指向尾元素下一个的位置,begin()却不是指向首元素上一个的位置,所以反向遍历用rbegin()。(迭代器可以–,但不能取代这个便捷方式)

key type

map和unordered_map若使用vector<int, int>、pair<int, int>等自定义类型作为key type,则需要重载<>运算符,因为其成员都需要能互相比较。否则会报错call to implicitly-deleted default constructor。
unordered_set也也是,但set可以直接用vector作为key type,却不能用pair<int, int>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值