C++基础知识(7)

43、STL是什么?

STL,英文全称 standard template library,中文可译为标准模板库。STL有六大组件:容器、迭代器、算法、仿函数、迭代器适配器、空间分配器。

主要使用的比较多的是容器,算法和迭代器。

(1)算法大致可以分为四类

​ (a)非可变序列算法:指不直接修改所操作的容器内容的算法

​ (b)可变序列算法:指可以修改它们所操作容器内容的算法

​ (c)排序算法:对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作

​ (d)数值算法:对容器内容进行数值计算

(2)容器是数据存放的形式,主要包括序列式容器和关联式容器,序列式容器有vector,list等,关联式容器有set,map等

(3)迭代器,类似指针,在不暴露容器内部结构的情况下对容器进行遍历。

44、迭代器的种类有哪些?

(1)输入迭代器:只读迭代器,在每个被遍历的位置上只能读取一次,例如find函数参数就是输入迭代器

(2)输出迭代器:只写迭代器,在每个被遍历的位置上只能被写一次

(3)前向迭代器:兼具输入和输出迭代器的能力,但是它可以对同一个位置重复进行读和写。但它不支持operator-,所以只能向前移动。

(4)双向迭代器:可以向前和向后移动

(5)随机访问迭代器:有双向迭代器的所有功能。而且,它还可以在一步内向前或者向后跳跃任意位置,即it+n、it-n、it+=n、it-=n、it1-it2、it[n]等操作。

45、STL中迭代器的作用,有指针为什么还需要迭代器?

(1)迭代器的作用

迭代器的作用就是在不需要暴露容器内部结构的情况下,按一定顺序访问容器各个元素。

(2)迭代器与指针的区别

迭代器不是指针,而且类模板,通过重载操作符,->、*、++、–等,来模拟指针的一些功能。其本质上是封装了原生的指针,提供比指针更高级的功能,相当于一种智能指针,可以根据不同类型的数据结构来实现不同的++,–等操作。

46、STL迭代器失效的情况

(1)插入操作

对于vector和string,如果容器内存被重新分配,迭代器、指针、引用都会失效;如果没有重新分配内存,那么插入点之前的迭代器有效,插入点之后的迭代器失效

对于deque,如果插入点位于除front和back的其他位置,迭代器、指针引都会失效;当我们插入元素到front和back时,deque的迭代器会失效,但是指针和引用有效;

对于list和forward_list,所有的迭代器和指针以及引用有效

(2)删除操作

对于vector和string,删除点之前的迭代器、指针、引用有效,而删除点之后的迭代器、指针、引用失效;

对于deque,如果删除点位于除front和back的其他位置,迭代器、指针、引用失效;当删除点位于front或back时,指向其他元素的迭代器、指针、引用有效;

对于list和forward_list,所有的迭代器、指针和引用都有效;

对于关联式容器map来说,如果某一个元素已经被删除了,那么其对应的迭代器就失效了,不应该再被使用。

47、STL迭代器如何删除元素

(1)对于序列式容器vector和deque来说,使用erase(itertor)后,虽然后面的每个元素的迭代器都会失效,但是后面每个元素都会往前移动一位,erase会返回下一个有效的迭代器,即便没有使用itertor去接收

vector<int>vec{1,2,3};
auto it = vec.begin();
erase(it);
std::cout<<*it<<std::endl; // 此时输出会是2;

(2)对于关联式容器map和set来说,使用了erase(itertor)后,当前元素的迭代器失效,但是其结构是红黑树,删除当前元素,不会影响下一个元素的使用,所以在调用erase之前记录下一个元素的迭代器即可

(3)对于list来说,它使用了不连续分配的内存,并且它的erase方法也会返回下一个有效的迭代器。

48、STL中resize和reserve的区别

(1)resize()

会改变当前容器元素的数量,当原来的容器size小于resize()后的size,那么会在元素的元素后面用0补充;当原来的容器size大于resize()后的size,那么原来容器后面的元素会被删除,直至满足resize()后的size

vector<int>vec{1,2,3};

vec.resize(2); // 此时vec内部只含有1,2两个元素
for(auto &num :vec) 
    std::cout<<num<<" "; 
std::cout<<std::endl;

vec.resize(5); // 此时vec内部含有1,2,0,0,0五个元素
for(auto &num :vec)
    std::cout<<num<<" "; 
std::cout<<std::endl;

vec.emplace_back(6); // 此时vec内部的元素为1,2,0,0,0,6
for(auto &num :vec)
    std::cout<<num<<" "; 
std::cout<<std::endl;

(2)reserve()

当reserve的参数比当前容器的容量小的时候并不会改变当前容器的容量,更加不会删除原本就存在于容器里面的元素;当reserve的参数比当前容器的容量大的时候,会改变当前容器的容量,但是不会添加元素。

vector<int>vec{1,2,3};
std::cout<<vec.capacity()<<endl; // 3
vec.emplace_back(4);
std::cout<<vec.capacity()<<endl; // 6

// 当reserve的参数比当前容量小
vec.reserve(1);
for(auto &num :vec)
    std::cout<<num<<" "; 
std::cout<<std::endl;   // 1,2,3,4
std::cout<<vec.capacity()<<endl; // 6

// 当reserve的参数比当前容量大
vec.reserve(10); // 10
for(auto &num :vec)
    std::cout<<num<<" "; 
std::cout<<std::endl; // 1,2,3,4
std::cout<<vec.capacity()<<endl; // 10

49、STL常用的容器

(1)vector,不定长数组,只能在尾部插入元素,支持随机访问

(2)deque,双端队列,头尾均可插入元素,支持随机访问

(3)queue,队列,先进先出,只能在头部出,在尾部插入

(4)stack,栈,先进后出,必须在栈顶入栈出栈

(5)priority_queue,优先队列,比queue增加了排序的功能,默认是大根堆(把大的元素放在堆顶)

(6)set,集合,默认升序排序,底层是红黑树,容器中的元素不重复

(7)multiset,多重集合,支持重复元素

(8)unordered_set,底层是哈希表,容器中的元素是无序的

(9)map,映射容器,底层是红黑树,默认按照key值升序排序

(10)multimap,key值可以重复,不支持[]访问,其他与map一样

(11)unordered_map,底层是哈希表,容器中的key值是无序的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

czy1219

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值