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 ...
随机推荐
- 二进制安装Kubernetes(k8s) v1.24.3 IPv4/IPv6双栈
二进制安装Kubernetes(k8s) v1.24.3 IPv4/IPv6双栈 Kubernetes 开源不易,帮忙点个star,谢谢了 介绍 kubernetes(k8s)二进制高可用安装部署,支 ...
- [Linux/Git]比较两份文件的差异
Command vim -d fileA fileB 或 git diff <oldCommitId> <newCommitId> X Recommend Files Matc ...
- 在IIS 搭建FTP站点
最近在项目中需要用到FTP,需要将生成的文件通过FTP上传网站. 在此记录下. FTP SSL设置,需要允许SSL连接. FTP 身份验证,匿名身份验证需要启用. FTP 授权规则,如果没有特殊情况允 ...
- DG:windows密码文件
问题描述:搭建DG,找不到密码文件的位置,就给备库重新生成了一个密码文件,传到了备库,但是拉到了备库以后,恢复过程中,trace日志在报错,后来才知道windows下的密码文件跟linux平台下的面文 ...
- Golang爬虫:使用正则表达式解析HTML
之前所写的爬虫都是基于Python,而用Go语言实现的爬虫具有更高的性能. 第一个爬虫 使用http库,发起http请求 package main import ( "fmt" & ...
- Go语言基础: goroutine和通道
并发编程表现为程序由若干个自主的活动单元组成. goroutine 在Go语言里,每一个并发执行的活动称为goroutine.当一个程序启动时,只有一个goroutine来调用main函数,称之为主g ...
- 笔记:C++学习之旅---顺序容器
笔记:C++学习之旅---顺序容器 STL = Standard Template Library 标准库模版 容器可以使用范围for输出或者迭代器进行输出 一个容器就是一些特定类型对象的集合.顺 ...
- 网络编程之java简易聊天室实现
最近浅学习了一些关于网络编程方面的知识,视频是跟着狂神学习的,可能学习的不是很深 说到网络,相信大家都对TCP.UDP和HTTP协议这些都不是很陌生,学习这部分应该先对端口.Ip地址这些基础知识有一定 ...
- python轻量级性能工具-Locust
Locust基于python的协程机制,打破了线程进程的限制,可以能够在一台测试机上跑高并发 性能测试基础 1.快慢:衡量系统的处理效率:响应时间 2.多少:衡量系统的处理能力:单位时间内能处理多少个 ...
- Web进阶LNMP网站部署
Web进阶LNMP网站部署 目录 Web进阶LNMP网站部署 LNMP架构工作流程 部署LNMP架构 1.安装nginx 2.安装php 3.安装数据库 将Nginx和PHP建立连接 1.修改ngin ...