《21天学通C++》(第十七章)STL 动态数组类(vector和deque)

server/2024/10/21 11:46:35/

std::vector的特点
1.在数组末尾添加元素所需的时间是固定的,删除亦是如此
2.在数组中间添加或删除元素所需的时间,和该元素后面的元素个数成正比
3.动态存储

1.实例化vector

实例化vector时,要指定该动态数组中存储的对象类型

std::vector<int> intArray;
std::vector<float> floatArray;

2.使用push_back()在末尾插入元素

std::vector<int> intArray; // 创建一个空的 intArray// 在末尾添加元素intArray.push_back(1);intArray.push_back(2);intArray.push_back(3);

3.列表初始化

std::vector<int> vec={1,3,5};

4.使用insert()在指定位置插入元素

插入单个元素

std::vector<int> vec = {1, 2, 4, 5};
auto it = vec.begin() + 2; // 指向索引2的位置,即元素4的迭代器
vec.insert(it, 3); // 在索引2的位置插入元素3,输出为1 2 3 4 5

插入多个相同元素

vec.insert(it, 2, 6); // 在it指向的位置之前插入两个6
//输出结果为1 2 6 6 4 5 

将另一个vector的元素插入

std::vector<int> anotherVec = {7, 8, 9};
vec.insert(it, anotherVec.begin(), anotherVec.end()); 
// 插入anotherVec中的所有元素,输出为1 2 7 8 9 4 5

5.使用数组语法访问vector中的元素

使用下标运算符[]和成员函数at()

下标运算符[]

#include <iostream>
#include <vector>int main() {std::vector<int> vec = {1, 2, 3, 4, 5};// 访问第二个元素(索引为1)int secondElement = vec[1];std::cout <<secondElement<< std::endl;//输出为2system("pause");return 0;
}

使用成员函数at()

#include <iostream>
#include <vector>int main() {std::vector<int> vec = {1, 2, 3, 4, 5};// 访问第二个元素(索引为1)int secondElement = vec.at(1);std::cout <<secondElement<< std::endl;//输出为2system("pause");return 0;
}

PS: 使用下标运算符。若索引超出了当前的元素范围,不会抛出异常,但成员函数at()会,会抛出 std::out_of_range异常,因为后者会在运行阶段检查容器的大小

6.使用指针语法(迭代器)访问vector中的元素

vec.begin()vec.end(),与vec.cbegin()vec.cend()的区别

  1. 可变性: begin() 和 end() 返回的迭代器允许修改元素,而 cbegin() 和 cend()
    返回的迭代器不允许修改,只能读取。
  2. 线程安全: 使用 cbegin() 和 cend() 在多线程环境中通常更安全,因为它们提供的是常量访问,不会改变容器的状态。
  3. const 正确性: 如果你在一个 const 容器对象上调用 begin() 或 end(),编译器会报错,因为这样违反了 const的约束。在这种情况下,你应该使用 cbegin() 或 cend()。
#include <iostream>
#include <vector>int main() {
std::vector<int> vec = {1, 2, 3};// 可变迭代器,允许修改元素
auto it = vec.begin();
*it = 10; // 合法// 常量迭代器,不允许修改元素
auto cit = vec.cbegin();
// *cit = 20; // 非法,会导致编译错误const std::vector<int> constVec = {1, 2, 3};
// auto it2 = constVec.begin(); // 非法,会导致编译错误
auto it2 = constVec.cbegin(); // 合法
system("pause");
return 0;
}

7.删除vector中的元素

使用pop_back() 将末尾的元素删除

#include <iostream>
#include <vector>int main() {
std::vector<int> vec = {1, 2, 3};auto it=vec.cbegin();
for(auto num:vec){std::cout<<num<<std::endl;
}vec.pop_back();
for(auto num:vec){std::cout<<num<<std::endl;
}system("pause");
return 0;
}

8.理解大小和容量

1.大小(size): std::vector 的大小指的是容器中实际存储的元素数量,使用size()函数获取。

2.容量(capacity) std::vector 的容量指的是容器当前分配的内存能够容纳的元素数量的最大值,使用capacity()函数获取。

#include <iostream>
#include <vector>int main() {std::vector<int> vec;// 初始时,大小为0,容量可能不为0std::cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;// 添加元素vec.push_back(1);vec.push_back(2);// 大小变为2,容量可能增加但大小不会改变std::cout << "After adding elements, Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;// 明确设置容量vec.reserve(100);// 容量至少为100,大小不变std::cout << "After reserving capacity, Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;system("pause");return 0;
}

9.STL deque类

也是一个STL动态数组类,但支持在数组的开头和末尾插入和删除元素,即提供双端队列的功能。记得添加头文件<deque>

添加元素:

  • push_back():在后端添加一个元素。
  • push_front():在前端添加一个元素。

删除元素:

  • pop_back():删除后端的元素。
  • pop_front():删除前端的元素。
#include <iostream>
#include <deque>int main() {std::deque<int> dq;// 在后端添加元素dq.push_back(10);dq.push_back(20);// 在前端添加元素dq.push_front(5);// 访问并打印所有元素for (int num : dq) {std::cout << num << " ";}std::cout << std::endl; // 输出 "5 10 20"// 删除前端元素dq.pop_front();// 删除后端元素dq.pop_back();// 再次访问并打印所有元素for (int num : dq) {std::cout << num << " ";}std::cout << std::endl; // 输出 "10"system("pause");return 0;
}

http://www.ppmy.cn/server/38957.html

相关文章

Hotcoin Research | 模块化将是大势所趋:拆解模块化区块链的现状和未来

关于模块化区块链叙事的讨论源于Celestia和其代币TIA的亮眼表现。实际上&#xff0c;模块化是未来区块链设计的主要发展方向和大势所趋。模块化区块链就像乐高积木一样&#xff0c;将区块链系统拆分为可重用的模块&#xff0c;通过定制组合可实现不同功能的区块链网络。这种灵活…

深入理解 ICMP 协议

目录 前言 1. 概述 特性与功能 报文封装与格式 2. ICMP差错报告 3. ICMP查询 4. ICMP应用 总结 前言 ICMP&#xff08;Internet Control Message Protocol&#xff09;是互联网控制报文协议&#xff0c;是TCP/IP协议族中的一个重要组成部分。作为网络层的协议之一&#…

初学python记录:力扣1652. 拆炸弹

题目&#xff1a; 你有一个炸弹需要拆除&#xff0c;时间紧迫&#xff01;你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k 。 为了获得正确的密码&#xff0c;你需要替换掉每一个数字。所有数字会 同时 被替换。 如果 k > 0 &#xff0c;将第 i 个数字用…

【微服务】网关(详细知识以及登录验证)

微服务网关 网关网关路由快速入门路由属性 路由断言网关登录校验自定义过滤器实现登录校验网关传递用户OpenFeign传递用户 网关 网络的关口&#xff0c;负责请求的路由&#xff0c;转发&#xff0c;身份校验 当我们把一个单体项目分成多个微服务并部署在多台服务器中&#xff…

Paddle 基于ANN(全连接神经网络)的GAN(生成对抗网络)实现

什么是GAN GAN是生成对抗网络&#xff0c;将会根据一个随机向量&#xff0c;实现数据的生成&#xff08;如生成手写数字、生成文本等&#xff09;。 GAN的训练过程中&#xff0c;需要有一个生成器G和一个鉴别器D. 生成器用于生成数据&#xff0c;鉴定器用于鉴定数据的准确性&…

Objective-C的对象复制与拷贝选项

对象复制与拷贝 文章目录 对象复制与拷贝copy与mutablecopycopy与mutablecopy的简介示例&#xff1a;不可变对象的复制可变对象的复制 NSCopying和NSMutableCopying协议深复刻和浅复刻浅拷贝&#xff08;Shallow Copy&#xff09;&#xff1a;深拷贝&#xff08;Deep Copy&…

vue3+vite+ts 自定义指令详解

directive-自定义指令&#xff08;属于破坏性更新&#xff09; Vue中有v-if,v-for,v-bind&#xff0c;v-show,v-model 等等一系列方便快捷的指令 今天一起来了解一下vue里提供的自定义指令 Vue3指令的钩子函数 created 元素初始化的时候 beforeMount 指令绑定到元素后调用 只调…

【C++】string类的使用②(容量接口Capacity || 元素获取Element access)

&#x1f525;个人主页&#xff1a; Forcible Bug Maker &#x1f525;专栏&#xff1a; STL || C 目录 前言&#x1f525;容量接口&#xff08;Capacity&#xff09;size和lengthcapacitymax_sizereserveresizeclearemptyshrink_to_fit &#x1f525;元素获取&#xff08;Ele…