C++面试八股文:用过std::set/std::map吗?
某日二师兄参加XXX科技公司的C++工程师开发岗位第27面:
面试官:用过
std::set/std::map吗?二师兄:用过。
面试官:能介绍一下二者吗?
二师兄:
std::set是一个有序的集合,其中的元素是唯一的,即每个元素只能出现一次。一般用于去重和自动排序。二师兄:
std::map同样是有序组合,只不过它不止有key,每个key还对用一个value。其中key是唯一,不可重复,但是value却没有限制。key/value也被称为键值对。面试官:知道他们底层使用什么数据结构存储数据的吗?
二师兄:两者都是使用红黑树作为底层的数据结构。红黑树是一种自动平衡的二叉树,它确保插入、删除和查找操作的时间复杂度都是
O(log n)。面试官:
set/map对于key的类型有什么要求吗?二师兄:因为
set/map被称为有序容器,所以对插入进去的key有排序的要求。一般需要为类型实现<比较方法,以下代码无法通过编译:
#include <iostream>
#include <set>
struct Foo
{
Foo(int v):val(v){}
int val;
};
int main(int argc, char const *argv[])
{
std::set<Foo> iset;
iset.insert(Foo(1024));
iset.insert(Foo(42));
for(auto it = iset.begin(); it != iset.end(); ++it)
{
std::cout << it->val << std::endl;
}
return 0;
}
二师兄:此时需要为
Foo类型实现bool operator<(const T&, const T&)函数,才能通过编译:
bool operator<(const Foo& lhs,const Foo& rhs) {return lhs.val < rhs.val;}
面试官:按照你的方法,可以实现从小到大的排序。如何实现从大到小的排序?
二师兄:
set/map类模板的第二个模板参数可以传入比较类型,默认比较类型是std::less<_Key>,我们可以传入std::greater<T>,此时需要实现bool operator>(const T&, const T&)函数。二师兄:还有一种方法是手写一个仿函数,重载
bool operator()(const T, const T) const函数用于比较两者的大小:
struct Comp
{
bool operator()(const Foo& lhs, const Foo& rhs) const
{
return lhs.val > rhs.val;
}
};
std::set<Foo,Comp> iset;
面试官:可以修改
map中的key吗?二师兄:不可以。因为
map中的key是const的。强制修改(取地址,const_cast转非const指针,解引用赋值)会造未知的错误。面试官:当
map中不存在某个key时,对map使用map[key]操作会有什么后果?二师兄:会在
map中增加一个键值对,键名为key,值是传入的value类型的默认值。面试官:如果不希望删除重复的
key,有什么办法?二师兄:STL中提供了
std::multiset和std::multimap两个容器,可以存入key相同的多个元素。面试官:在
std::multimap中如何通过key查找value?二师兄:
multimap提供了equal_range方法,此方法返回一个pair,分别对应2个迭代器。通过循环迭代器来获取key对应的所有value。
#include <iostream>
#include <map>
int main() {
std::multimap<int, std::string> mmap;
mmap.insert(std::make_pair(1, "1"));
mmap.insert(std::make_pair(2, "2"));
mmap.insert(std::make_pair(3, "3"));
mmap.insert(std::make_pair(1, "1"));
auto range = mmap.equal_range(1);
for (auto it = range.first; it != range.second; ++it) {
std::cout << it->second << std::endl;
}
return 0;
}
面试官:最后一个问题,你觉得单纯的查询而言,是
vector快还是map快?二师兄:当然是
map快,因为vector的查询的时间复杂度是O(n),而map是O(logn)。面试官:好的,今天面试结束了,回去等通知吧。
让我们看看最后一个问题:
单纯的查询而言,是
vector快还是map快?
这里二师兄的是标准答案,实际上当数据量特别大的时候,的确map是更好的选择。
但当数据量没那么大的时候(少于1000条记录),vector要比map查询速度快。原因我们在之前的面试文章中讲过,vector内存连续,缓存更友好。map底层是红黑树,内存并不连续。
当数据量小的时候,算法的优势没有抵消缓存的劣势,所以vector在数据量小的时候更胜一筹。
“纸上得来终觉浅,绝知此事要躬行”。小伙伴们,一起努力吧!
关注我,带你21天“精通”C++!(狗头)
C++面试八股文:用过std::set/std::map吗?的更多相关文章
- 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 ...
- 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 ...
- 单独删除std::vector <std::vector<string> > 的所有元素
下面为测试代码: 1.创建 std::vector< std::vector<string> > vc2; 2.初始化 std::vector<string> vc ...
- C++11 std::bind std::function 高级使用方法
从最基础的了解,std::bind和std::function /* * File: main.cpp * Author: Vicky.H * Email: eclipser@163.com */ # ...
- 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++> 给出排序好的 ...
- 没有与这些操作数匹配的 "<<" 运算符 操作数类型为: std::ostream << std::string
错误显示:没有与这些操作数匹配的 "<<" 运算符 操作数类型为: std::ostream << std::string 错误改正:要在头文 ...
- matlab转c++代码实现(主要包含C++ std::vector,std::pair学习,包含数组与常数相乘,数组相加减,将数组拉成一维向量,图片的读入等内容)
MATLAB部分: xmap = repmat( linspace( -regionW/2, regionW/2, regionW), regionH, 1 );%linspace [x1,x2,N] ...
- std::lock_guard/std::unique_lock
C++多线程编程中通常会对共享的数据进行写保护,以防止多线程在对共享数据成员进行读写时造成资源争抢导致程序出现未定义的行为.通常的做法是在修改共享数据成员的时候进行加锁--mutex.在使用锁的时候通 ...
- std::binary_serach, std::upper_bound以及std::lower_bound
c++二分查找的用法 主要是 std::binary_serach, std::upper_bound以及std::lower_bound 的用法,示例如下: std::vector<int& ...
- C++11 并发指南四(<future> 详解三 std::future & std::shared_future)
上一讲<C++11 并发指南四(<future> 详解二 std::packaged_task 介绍)>主要介绍了 <future> 头文件中的 std::pack ...
随机推荐
- 【性能优化】优雅地优化慢查询:缓存+SQL修改组合拳
问题描述 单例数据库模式中,后端高并发请求多(读多写少),导致数据库压力过大,关键接口响应变慢,严重影响体验. 需求 减少接口的响应时间. 寻找解决方案 由于问题主要处在数据库压力过大的情况,采用两种 ...
- IIS部署网站,运行网站时出现的错误
大概情况就是一台新电脑在部署IIS中出现的各种问题,做了一个整合,大部分都是找的别人写的博客,但是有的原文连接找不到了,见谅! 问题: 不能在此路径中使用此配置节.如果在父级别上锁定了该节,便 ...
- nlp数据预处理:词库、词典与语料库
在nlp的数据预处理中,我们通常需要根据原始数据集做出如题目所示的三种结构.但是新手(我自己)常常会感到混乱,因此特意整理一下 1.词库 词库是最先需要处理出的数据形式,即将原数据集按空格分词或者使用 ...
- Vue闪烁的问题
问题: 当我们打开Vue页面的时候,如果弱网环境,会出现一个闪烁的效果 原因: Vue还来不及处理的模板 解决: 使用 v-cloak 来解决Vue这个打开页面的闪烁的问题 原理: 利用 v-cloa ...
- 创建SpringBoot项目,在yml中配置数据库, driver-class-name: com.mysql.cj.jdbc.Driver标红报错解决方式
一.报错原因 com.mysql.cj.jdbc.Driver一直标红报错,原因在于pom.xml中mysql包没有下载下来,或者在创建项目的时候有问题 二.解决方案 在pom.xml添加 <d ...
- python 高级函数补充
补充几个高级函数 zip 把两个可迭代内容生成一个可迭代的tuple元素类型组成的内容 # zip 案例 l1 = [ 1,2,3,4,5] l2 = [11,22,33,44,55] z = zip ...
- Azure Devops上模版化K8s部署
在2022年我们终于完成了主要业务系统上K8s的计划,在这里总结下我们上K8s时候的模版工程. 前提条件 本文不讨论K8s是什么,什么是容器化,为什么需要容器化,什么是微服务等这些基础内容,这些到处说 ...
- 深入理解 slab cache 内存分配全链路实现
本文源码部分基于内核 5.4 版本讨论 在经过上篇文章 <从内核源码看 slab 内存池的创建初始化流程> 的介绍之后,我们最终得到下面这幅 slab cache 的完整架构图: 本文笔者 ...
- 【Redis】持久化实现(RDB、AOF)
一.Redis RDB 持久化 1.RDB 工作原理 RDB(Redis Database)基于时间进行生成数据快照,默认只保留当前最新数据状态,优点时执行速度较快,但上次数据保存点到当前时间点之间的 ...
- Centos7 部署Django项目 uwsgi + nginx
启动 首先确保你的django项目是可以在虚拟环境中跑起来的,环境管理窝用的是pyenv,pyenv不知道什么东西的可以参考窝之前写过的Pyenv环境管理的安装文. 项目启动 python manag ...