当前位置: 首页 > news >正文

C/C++复习(四)

一.模版

模版涉及的是泛型编程,即通过编译器去确定类型的编程方式,模版分为:类模板和函数模版,下面我们一一复习:

函数模版:

格式:

template<typename T1, typename T2,......,typename Tn>
返回值类型 函数名(参数列表){}
//注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)//模版既可以为typename,也可以为size_t

对于函数模版,原理就是通过编译器在编译时通过传入的实参来推导形参对应的类型,然后产生专门对应的类型代码,如下:

//模版:
template<class T>
void swap(T& a,T& b)
{T c=a;a=b;b=c;
}int main()
{//调用:int a=10,b=20;swap(a,b);//会去生成下面内容->最后面    return 0;
}//生成的代码:
void swap(int a,int b)
{int c=a;a=b;b=c;
}

函数模版的实例化分为显示实例化和隐式实例化,上面由编译器推导的都是隐式实例化,显示实例化是指调用时,由用户指定类型,从而直接传递类型,如下:

//直接写调用,还是swapint main()
{double d1=1.2;double d2=2.5;swap<double>(d1,d2);return 0;
}//注意点:
//如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错

类模板:

格式:

template<class T1, class T2, ..., class Tn>
class 类模板名
{// 类内成员定义
};

类模版大体与函数模版相似使用即可,不同的是类模板实例化必须在类模板名字后跟<>,然后将实例化的类型放在<>,类模板名字不是真正的类,而实例化的结果才是真正的类

然后就是大家还可以去复习下全特化与偏特化内容,然后还有模版最好不要分离编译,使用.hpp,大家可以参考下面博客复习:

C++之模版详解-CSDN博客



二.容器常见知识点

1.vector与list区别?

1.底层实现上:
vector底层是一段连续的顺序表,而list是带头结点的双向循环链表,底层不连续
2.访问上:
vector由于其底层连续,可以支持下标随机访问,list不支持随机访问,必须要遍历查找
3.操作上:
插入:vector任意位置插入由于可能需要挪动空间、开辟新空间,整体拷贝效率非常低下,list插入只需要改变指针指向和开辟一个节点空间即可,效率高
删除:vector除尾删外任意位置删除都要挪动空间,效率低,而list不需要挪动空间,只需要改变指针指向,效率高
4.空间利用上:
vector是连续的顺序表,不易造成空间碎片化,而list是通过指针将节点相连,各节点之间不连续,空间碎片化严重,空间利用率低
5.迭代器上:
vector是使用原生态的迭代器(即只是指针),list是将原生态迭代器进行了封装,可以参考我的github:
https://github.com/zhutishou/C-STL-Copywriting/blob/main/list.cpp
6.使用场景上:
vector适用于高效存储和随机访问上,不关系插入和删除效率;list适用于大量插入和删除上,不注重空间利用和随机访问

2.vector如何实现插入?

1.首先,先判断插入位置是否正确
2.检查空间是否需要扩容
3.将要插入以后的元素整体后移
4.插入当前位置
5.返回插入位置的迭代器
//具体代码如下:
//插入:
//插入:
iterator insert(iterator pos,const T& val)
{if(pos < _begin|| pos > _end){std::cerr<<"该位置不存在"<<std::endl;}//判断是否需要扩容:if(_end == _endofstorage){size_t len = _begin + pos;reserve(capacity()==0?4:2*capacity());pos = _begin + len;}//pos后续位置后移:iterator finish = _end -1;while(finish > pos){*(finish+1) = *finish;finish--;}*pos = val;_end++;return pos;
}
//vector实现代码如下:
https://github.com/zhutishou/C-STL-Copywriting/blob/main/vector.cpp

3.vector和list都有缺陷,是否存在其他容器可以兼顾两者优点呢?

能够兼顾vector和list优点的容器就是deque(双端队列)
介绍:
deque是双开口的“连续”空间的数据结构,注意:“连续”实际上是一段段小空间拼凑出来的,只是支持下标随机访问看做连续,支持头插尾插,并且不需要挪动元素
相比于vector和list优点:
1.相比于vector头插尾插O(1),不用挪动数据,并且扩容时,不需要整体拷贝
2.相比于list,空间利用率更高缺点:
不适合遍历,由于其底层是一个个小空间实现的,迭代器需要不断检查边界,效率低下,因此通常还是使用vector或list使用场景:
deque通常是stack和queue空间适配器默认的容器,原因是因为两者都不需要遍历,而且只在首尾操作

4.map和set底层是什么?

对于map/set和unordered_map/unordered_set这是我们必须掌握的
map/set底层是红黑树,unordered_map/unordered_set底层是哈希表
该问题实际上是问红黑树的相关信息:
一.规则:
1. 每个结点不是红色就是黑色
2. 根节点是黑色的
3. 如果一个节点是红色的,则它的两个孩子结点是黑色的
4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点
5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)
红黑树通过规则2、3保证树的其最长路径中节点个数不会超过最短路径节点个数的两倍
效率:
红黑树是一个高效的平衡二叉树,增删查改效率都是O(LogN)
实现:
可以参考我的github注意:
multimap和multiset也是红黑树实现的,但是与set/map不同点在于这两个允许出现重复的key值

5.map的operator[]是如何实现的?

V& operator[](const K& key)//V --- value 
{ return (*(_t.Insert(ValueType(key, V()))).first).second;
}operator[]如果存在key,就返回对应的value,如果不存在key,就插入key,返回默认值

6.一个什么类型才能做map和set的key值?

map和set底层都是红黑树,而红黑树是平衡搜索树,所以一定支持比较大小,当然提供相应的仿函数来比较大小的类型也是可以的

7.unordered_map和unordered_set是如何实现的?

这个问题本质上是询问我们其底层实现,显然这两者都是通过哈希实现的,那么就讲述哈希特点
规则:
哈希是通过哈希函数进行相应的映射关系,使key与存储位置建立一一的映射,在查找时就可以快速找到
对比:
哈希在查找时效率为O(1),而红黑树效率为O(LogN),顺序表效率为O(N)
常见问题:
哈希冲突:
该问题无法避免,是指不同关键字通过相同哈希哈数计算出相同的哈希地址,该种现象称为哈希冲突或哈希碰撞,解决方法:建立合适的空间大小,减少通过哈希函数计算之后碰撞的发生,还有两种常见处理方法:开散列和闭散列

8.一个类型做unordered_map和unordered_set的key有什么要求?

哈希是需要通过哈希函数进行映射的,所以key值必须可以实现向整数的转换,这样才能映射到存储空间中

最后,感谢你的支持!!!

http://www.dtcms.com/a/336025.html

相关文章:

  • 【LeetCode】单链表经典算法:移除元素,反转链表,约瑟夫环问题,找中间节点,分割链表
  • Javascript面试题及详细答案150道之(106-120)
  • 深度学习——常见的神经网络
  • Tomcat 类加载器原理深度解析
  • PowerPoint和WPS演示让多个对象通过动画同时出现
  • 近期(2021-2025)发行的常用国军标GJB 整理,2021,2022,2023,2024,2025
  • 深入理解QFlags:Qt中的位标志管理工具
  • 本文将详细介绍如何构建一个功能完整的键盘测试工具,包含虚拟键盘、实时统计、打字练习等核心功能,无需任何后端服务或复杂依赖。
  • 无人机视角土地区域类型识别分割数据集labelme格式4904张7类别
  • 使用oradebug收集数据库诊断信息
  • 第3章 Java NIO核心详解
  • AOP配置类自动注入
  • Linux系统分析 CPU 性能问题的工具汇总
  • 【102页PPT】某著名企业智能制造解决方案及智能工厂产品介绍(附下载方式)
  • 19.5 「4步压缩大模型:GPTQ量化实战让OPT-1.3B显存直降75%」
  • 微网智能光储协调控制器方案
  • 【运维进阶】实施任务控制
  • 网络原理与编程实战:从 TCP/IP 到 HTTP/HTTPS
  • 基于Vue的个人博客网站的设计与实现/基于node.js的博客系统的设计与实现#express框架、vscode
  • Rust 入门 生命周期(十八)
  • 力扣3:无重复字符的最长子串
  • Linux软件编程:进程与线程(线程)
  • 最新技术论坛技术动态综述
  • 【论文阅读】美 MBSE 方法发展分析及启示(2024)
  • 多维视角下离子的特性、应用与前沿探索
  • RabbitMQ面试精讲 Day 24:消费者限流与批量处理
  • 从0实现系统设计
  • Python 类元编程(类作为对象)
  • Makefile介绍(Makefile教程)(C/C++编译构建、自动化构建工具)
  • 为什么神经网络在长时间训练过程中会存在稠密特征图退化的问题