某日二师兄参加XXX科技公司的C++工程师开发岗位第27面:

面试官:知道std::unordered_set/std::unordered_map吗?

二师兄:知道。两者都是C++11引入的新容器,和std::setstd::map功能类似,key唯一,unordered_mapvalue可变。

二师兄:不同于set/mapunordered_set/unordered_map都是无序容器。

面试官:那你知道它们底层怎么实现的吗?

二师兄:两者底层使用哈希表实现,因此插入、删除和查找操作的平均时间复杂度为常数时间O(1)

面试官:既然平均复杂度是O(1),那么是不是可以取代setmap了?

二师兄:这里是平均的时间复杂度。哈希表插入、删除和查找操作的最差时间复杂度是O(n),要比set/mapO(log n)大。

面试官:那你觉得哪些场景适合set/map,哪些场景适合unordered_set/unordered_map

二师兄:set/map适用于需要有序存储和快速查找的场景,而unordered_set/unordered_map适用于需要快速插入和查找的场景。

面试官:unordered_set/unordered_map对于key的类型有什么要求吗?

二师兄:因为unordered_set/unordered_map底层采用哈希表,所以在使用自定义类型作为key的时候,需要告诉编译器如何计算此类型的hash值,同时还要告诉编译器如何判断两个自定义类型的对象是否相等。以下代码无法通过编译:

#include <iostream>
#include <unordered_set>
struct Foo
{
std::string str;
int val;
};
int main(int argc, char const *argv[])
{
std::unordered_set<Foo> uset;
uset.insert({"42",42});
uset.insert({"1024",1024});
return 0;
}

二师兄:此时需要为Foo类型实现bool operator==(const Foo& o) const函数和size_t operator()(const Foo& f) const仿函数,才能通过编译:

#include <iostream>
#include <unordered_set>
struct Foo
{
std::string str;
int val;
bool operator==(const Foo& o) const
{
return str == o.str && val == o.val;
}
};
struct Hash
{
size_t operator()(const Foo& f) const
{
return std::hash<std::string>()(f.str) ^ std::hash<int>()(f.val);
}
};
int main(int argc, char const *argv[])
{
std::unordered_set<Foo,Hash> uset;
uset.insert({"42",42});
uset.insert({"1024",1024});
return 0;
}

二师兄:当然我们也可以使用std::function或者lambda来代替仿函数,目的都是为了使得编译器知道如何计算自定义类型的哈希值。

面试官:用过unordered_multiset/unordered_multimap吗?

二师兄:没用过。但是应该和multiset/multimap类似,只是底层也采用hash表实现。

面试官:好的,今天的面试就结束了,请回去等消息吧。

对于今天面试官的表现,小伙伴们能给几分呢?不是面试官要放水,面完set/map之后再面unordered_set/unordered_map,真的没有那么多好问题,因为两者太像了。。。

好了,今天的面试到这里就结束了,让我们期待明天面试官的表现吧~

关注我,带你21天“精通”C++!(狗头)

C++面试八股文:知道std::unordered_set/std::unordered_map吗?的更多相关文章

  1. std::hash<std::pair<int, int> >

    标题是搞笑的 ! 这个问题只需要 since C++11 问题:怎么让 unordered_map 支持使用 pair 作为 key? 如果你能把两个东西压到一个基本类型里那么就不用解决这个问题了 . ...

  2. c++ std::unordered_set

    std::unordered_set template < class Key, // unordered_set::key_type/value_type class Hash = hash& ...

  3. E0443类模板 "std::unordered_set" 的参数太多

    1>------ 已启动全部重新生成: 项目: QtGuiApplication20190416, 配置: Debug x64 ------1>Uic'ing QtGuiApplicati ...

  4. C++ folly库解读(三)Synchronized —— 比std::lock_guard/std::unique_lock更易用、功能更强大的同步机制

    目录 传统同步方案的缺点 folly/Synchronized.h 简单使用 Synchronized的模板参数 withLock()/withRLock()/withWLock() -- 更易用的加 ...

  5. std::unique_lock<std::mutex> or std::lock_guard<std::mutex> C++11 区别

    http://stackoverflow.com/questions/20516773/stdunique-lockstdmutex-or-stdlock-guardstdmutex The diff ...

  6. hdu 1053 (huffman coding, greedy algorithm, std::partition, std::priority_queue ) 分类: hdoj 2015-06-18 19:11 22人阅读 评论(0) 收藏

    huffman coding, greedy algorithm. std::priority_queue, std::partition, when i use the three commente ...

  7. 单独删除std::vector <std::vector<string> > 的所有元素

    下面为测试代码: 1.创建 std::vector< std::vector<string> > vc2; 2.初始化 std::vector<string> vc ...

  8. C++11 std::bind std::function 高级使用方法

    从最基础的了解,std::bind和std::function /* * File: main.cpp * Author: Vicky.H * Email: eclipser@163.com */ # ...

  9. LeetCode 26 Remove Duplicates from Sorted Array [Array/std::distance/std::unique] <c++>

    LeetCode 26 Remove Duplicates from Sorted Array [Array/std::distance/std::unique] <c++> 给出排序好的 ...

  10. 没有与这些操作数匹配的 "<<" 运算符 操作数类型为: std::ostream << std::string

    错误显示:没有与这些操作数匹配的 "<<" 运算符       操作数类型为:  std::ostream << std::string 错误改正:要在头文 ...

随机推荐

  1. github打不开或者打开慢方法

    github最近打不开,很久之前遇到过,但是忘记怎么解决了,查找相关资料后,今天记录在此,以备不时之需. 记住3个关键网址 github网址查询:The world's leading softwar ...

  2. [数据库/ORALCE]导入/导出数据

    ORACLE数据导入/导出 工具介绍:EXP/IMP | EXPDP/IMPDP EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用. EXPDP和IMPDP是服务端的工具程序 ...

  3. 为什么一定要用Redis?

    参考: 为什么分布式一定要有Redis? 选redis还是memcache,源码怎么说?

  4. MySQL(十四)分析查询语句Explain 七千字总结

    分析查询语句:EXPLAIN 1概述 ​ 定位了查询慢的SQL之后,就可以使用EXPLAIN或者DESCRIBE工具做针对性的分析查询.两者使用方法相同,并且分析结果也是相同的. ​ MySQL中有专 ...

  5. JUC(二)线程间通信

    目录 线程间通信 多线程编程步骤 一个加减实例 & 虚假唤醒问题 Lock接口实现 lock.newCondition设置等待条件 线程间定制化通信 线程间通信案例 设置标志位 线程间通信 多 ...

  6. mysql安装my.cnf配置

    进入my.cnf文件//乱码修改 设置编码 character_set_server = utf8mb4 //编码 collation-server = utf8mb4_general_ci //连接 ...

  7. 纯前端使用xlsx实现导出表格

    列表数据纯前端使用xlsx实现导出功能 基础写法 let filename = "资产导出.xlsx"; 定义导出数据 let data = [ ["第一列", ...

  8. 一文掌握ArrayList和LinkedList源码解读

    大家好,我是Leo! 今天来看一下ArrayList和LinkedList的源码,主要是看一下常用的方法,包括像add.get.remove方法,大部分都是从源码直接解读的,相信大家读完都会有一定收获 ...

  9. 终端命令行前出现(base)

    原因 (base) 的出现是因为电脑安装了conda后,每次打开终端都会自动启动conda的base环境 解决 取消自动启动base环境:conda config --set auto_activat ...

  10. 深入理解前端字节二进制知识以及相关API

    当前,前端对二进制数据有许多的API可以使用,这丰富了前端对文件数据的处理能力,有了这些能力,就能够对图片等文件的数据进行各种处理. 本文将着重介绍一些前端二进制数据处理相关的API知识,如Blob. ...