【C++】vector的介绍 | 常见接口的使用

news2024/11/25 4:45:37

目录

vector的介绍

常见接口

构造函数

尾插push_back()

vector的遍历

1.用方括号+下标 遍历:

2.调用at()来访问:

3.用迭代器遍历:

4.范围for遍历:

vector空间

vector增删查改

覆盖assign()

查找find()

插入insert()

删除erase()


本篇先对vector做一个介绍,然后把常用的接口演示一下。

由于vector的许多接口和string那儿的高度重合,所以这里就不详讲了,主要做一个了解。只要掌握几个最重要的接口,其余的用到时 查文档就好。

vector的介绍

vector是一个类模板。它能够容纳各种类型的对象作为其元素,并且可以动态地调整大小。可以理解为动态数组

它像数组,又不像。

像数组的是:vector也采用的连续存储空间来存储元素。这意味着可以采用下标对vector的元素进行访问,和数组一样高效。

不像数组的是:它的大小是可以动态改变的,而且它的大小会被容器自动处理。

本质来说,vector使用动态分配数组来存储它的元素。

当新元素插入时候,这个数组需要被重新分配大小,为了增加存储空间。

其做法是,分配一个新的数组,然后将全部元素移到这个数组。

就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。

vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。

不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。

因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。

与其它动态序列容器相比(deque、list 、forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。

对于其他不在末尾的删除和插入操作,效率更低。

常见接口

包头文件:

#include<vector>

构造函数

两个标了🚩的要记住:

构造函数声明接口说明
vector();(重点)🚩无参构造
vector(size_type n, const value_type& val = value_type());构造并初始化n个val
vector (const vector& x); 🚩拷贝构造
vector (InputIterator first, InputIterator last);使用迭代器进行初始化构造

我们在使用时,要注意vector是一个类模板,要实例化成 具体的类型 来使用:

vector<int> v1;        //创建一个int类型的,空的v1
​
vector<int> v2(5, 1);  //v2含5个1
​
vector<int> v3(v2);   //拷贝构造
​
vector<int> v4(v3.begin(), v3.end());   //用迭代器

尾插push_back()

vector没有头插 / 头删(因为每次都要挪数据,效率太低),也不能用operator+=,

它只能尾插 / 尾删,或者insert/erase。总之,就是一个一个地插入、删除。

#include<vector>
using namespace std;
​
int main()
{
    vector<int> v1;      
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);
    v1.push_back(4);
    return 0;
}

相关接口:尾删pop_back()

vector的遍历

先说明一下:

vector是不能直接用流插入输出的:

 

因为vector是一个容器,它可以存储多个元素。

而流插入输出操作符<<是用于将一个单独的元素插入到流中的,而不是将整个容器插入到流中。

因此,如果要将vector中的元素输出到流中,需要使用循环逐个输出

现在我们就来看看遍历输出vector的4种方法:

1.用方括号+下标 遍历:

vector是支持operator[]和size()的,因此可以用 方括号+下标 的方式遍历。

#include<iostream>
#include<vector>
using namespace std;
​
int main()
{
    vector<int> v;      
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
​
    for (size_t i = 0; i < v.size(); i++)
    {
        cout << v[i] << " ";
    }
    return 0;
}

2.调用at()来访问:

 

at()是像函数一样调用的:

for (size_t i = 0; i < v.size(); i++)
    {
        cout << v.at(i) << " ";
    }

这里补充一下at()和operator[]的区别:两者检查越界的方式不一样。

at()是较温和的抛异常:

而operator[]是断言:

3.用迭代器遍历:

vector<int>::iterator it = v.begin();
while (it != v.end())
{
    cout << *it << " ";
    it++;
}

4.范围for遍历:

for (auto& e : v)
{
    cout << e << " ";
}

vector空间

容量空间接口说明
size获取数据个数
capacity获取容量大小
empty判断是否为空
resize (重点)改变vector的size
reserve (重点)改变vector的capacity

这些接口的功能、用法都和string里的类似,就不详讲了。

这里要说下,capacity在vs下和在g++下的增长问题:

vs下capacity是按1.5倍增长的,g++是按2倍增长的。

这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。

来测试下:

vs

#include<vector>
#include<iostream>
using namespace std;
​
int main()
{
    vector<int> v;   
    int val = v.capacity();
    for (size_t i = 0; i < 100; i++)
    {
        v.push_back(i);
        if (val != v.capacity())
        {
            cout <<"now the capacity is:  "<< v.capacity() << endl;
        }
        val = v.capacity();
    }
    return 0;
}

g++:

vector增删查改

覆盖assign()

assign:将新内容指定给vector,替换其当前内容,并相应地修改其size。也就是说,起到一个替换、覆盖的作用。

演示:

#include<vector>
#include<iostream>
using namespace std;
​
int main()
{
    vector<int> v;   
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    for (auto& e : v)
    {
        cout << e << " ";
    }
    cout << endl;
​
    v.assign(8, 8);
    for (auto& e : v)
    {
        cout << e << " ";
    }
    return 0;
}

查找find()

其实vector的接口里并未提供find(),不光是vector,list、deque等容器中也没有该函数。

这是因为像vector、list、deque等容器,它们都是从头到尾遍历查找,查找逻辑是相同的。

而在算法库<algorithm>中,find()是一个类模板算法,所有的容器都可以复用,想用时直接套上去用,因此没必要单独实现find()接口了。

注意:

1.要包<algorithm>头文件。

2.迭代器区间,都是左闭右开的 :[ first,last )

3.返回的是迭代器。如果找到了val,返回val的迭代器;如果没找到,返回last,即右边开区间的位置。

示例:

#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
​
int main()
{
    vector<int> v;   
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    vector<int>::iterator it = find(v.begin(), v.end(), 3);
    cout << *it << endl;
    return 0;
}

插入insert()

 

有了insert(),我们可以实现自由插入了,包括头插。

现在我们就在2的前面插入一个100:

int main()
{
    vector<int> v;   
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    
    vector<int>::iterator pos = find(v.begin(), v.end(), 2);   //先找到2的位置pos
    if (pos != v.end())
    {
        vector<int>::iterator it = v.insert(pos, 100);     //在pos位置插入100,2被挤到后一个
    }
    
    for (auto& e : v)
    {
        cout << e << " ";
    }
    return 0;
}

删除erase()

 

示例:

int main()
{
    vector<int> v;   
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
​
    vector<int>::iterator pos = find(v.begin(), v.end(), 2);
    if (pos != v.end())
    {
        v.erase(pos);
    }
    for (auto& e : v)
    {
        cout << e << " ";
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1050760.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

css自学框架之幻灯片展示效果

这一节&#xff0c;我自学了焦点图效果(自动播放&#xff0c;圆点控制)&#xff0c;首先看一下效果&#xff1a; 下面我们还是老思路&#xff0c;css展示学习三个主要步骤&#xff1a;一是CSS代码&#xff0c;二是Javascript代码&#xff0c;三是Html代码。 一、css代码主要如…

【JavaEE】锁策略

文章目录 前言1. 乐观锁和悲观锁2. 重量级锁和轻量级锁3. 自旋锁和挂起等待锁4. 公平锁和非公平锁5. 可重入锁和非可重入锁6. 读写锁Java synchronized 分别对应哪些锁策略1. 乐观锁和悲观锁2. 重量级锁和轻量级锁3. 自旋锁和挂起等待锁4. 公平锁和非公平锁5. 可重入锁和非可重…

Scala第八章节

Scala第八章节 scala总目录 章节目标 能够使用trait独立完成适配器, 模板方法, 职责链设计模式能够独立叙述trait的构造机制能够了解trait继承class的写法能够独立完成程序员案例 1. 特质入门 1.1 概述 有些时候, 我们会遇到一些特定的需求, 即: 在不影响当前继承体系的情…

基于Java的图书管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

JavaScript系列从入门到精通系列第十篇:JavaScript中的相等运算符与条件运算符

文章目录 一&#xff1a;相等运算符 1&#xff1a; 2&#xff1a;! 3&#xff1a;与! (一)&#xff1a; (二)&#xff1a;! 二&#xff1a;条件运算符 1&#xff1a;语法 2&#xff1a;使用 3&#xff1a;容易挨打的写法 一&#xff1a;相等运算符 用于比较两个值是…

前端框架介绍

一、node.js 配置淘宝镜像源 npm config set registry https://registry.npm.taobao.org可以使用npm config list命令来确认镜像地址是否已成功更改。 如果需要将配置的镜像恢复为默认的npm官方源,可以执行以下命令: npm config delete registry二、vue 1、创建Vue项目 …

算法的时间复杂度分析习题专题

之前写了一篇重点是讲理论&#xff0c;今天重点在于对于题目的分析 题目难度不分先后&#xff0c;有题目来源会直接给出链接或者位置 第一题&#xff1a;消失的数字 题目来源&#xff1a;LeetCode消失的数字 分析 第一种思路分析&#xff1a; 参考代码&#xff1a; #include …

RTSP协议抓包及讲解

文章目录 前言一、RTSP 亲手搭建直播点播1、数据源为视频文件2、数据源为摄像头①、搭建 RTSP 流媒体服务器②、客户端拉流 二、RTSP 协议简介三、手撕 RTSP 协议1、Wireshark 抓包①、搭建环境②、wireshark 抓包 2、RTSP 交互流程①、OPTIONS②、DESCRIBE③、SETUP④、PLAY⑤…

全面横扫:dlib Python API在Linux和Windows的配置方案

前言 在计算机视觉和人工智能领域&#xff0c;dlib是一个备受推崇的工具库。它为开发者提供了强大的图像处理、机器学习和深度学习功能。在计算机视觉项目中&#xff0c;配置dlib Python API是一个重要的初始步骤。本文将引导读者详细了解在Linux和Windows系统上安装和配置dli…

【算法分析与设计】动态规划(下)

目录 一、最长公共子序列1.1 最长公共子序列的结构1.2 子问题的递归结构1.3 计算最优值1.4 举例说明1.5 算法的改进 二、最大子段和2.1 代码2.2 最大子段和问题的分治算法2.3 代码2.4 分治算法的时间复杂度2.5 最大子段和问题的动态规划算法 三、凸多边形最优三角剖分3.1 三角剖…

Flutter笔记:关于应用程序中提交图片作为头像

Flutter笔记 关于应用程序中提交图片作为头像 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/133418554…

raw智能照片处理工具DxO PureRAW mac介绍

DxO PureRAW Mac版是一款raw智能照片处理工具&#xff0c;该软件采用了智能技术&#xff0c;以解决影响所有RAW文件的七个问题&#xff1a;去马赛克&#xff0c;降噪&#xff0c;波纹&#xff0c;变形&#xff0c;色差&#xff0c;不想要的渐晕&#xff0c;以及缺乏清晰度。 Dx…

软件测试之单元测试自动化入门基础

单元测试自动化 所谓的单元测试(Unit Test)是根据特定的输入数据&#xff0c;针对程序代码中的最小实体单元的输入输出的正确性进行验证测试的过程。所谓的最小实体单元就是组织项目代码的最基本代码结构&#xff1a;函数&#xff0c;类&#xff0c;模块等。在Python中比较知名…

picoctf_2018_got_shell

picoctf_2018_got_shell Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)32位&#xff0c;只开了NX int __cdecl __noreturn main(int argc, const char **argv, const char **envp) {_DWOR…

DeepFace【部署 02】轻量级人脸识别和面部属性分析框架(实时分析+API+Docker部署+命令行接口)

轻量级人脸识别和面部属性分析框架 2.10 Real Time Analysis2.11 API2.12 Dockerized Service2.13 Command Line Interface 2.10 Real Time Analysis 你也可以运行deepface实时视频。流功能将访问您的网络摄像头&#xff0c;并应用面部识别和面部属性分析。如果能连续聚焦5帧&…

2023-9-29 LCR 083 全排列

题目链接&#xff1a;全排列 class Solution {int [] nums;List<List<Integer>> res new ArrayList<>();List<Integer> path;boolean[] st;public List<List<Integer>> permute(int[] nums) {this.nums nums;path Arrays.asList(new In…

DAMA-DMBOK2重点知识整理CDGA/CDGP——第14章 大数据与数据科学

目录 一、分值分布 二、重点知识梳理 1、引言 1.1 业务驱动因素 1.2 原则 1.3 基本理念 2、活动 2.1 定义大数据战略和业务需求 2.2 选择数据源 2.3 获得和接收数据源 2.4 制定数据假设和方法 2.5 集成和调整数据进行分析 2.6 使用模型探索数据 2.7 部署和监控 …

09链表-单链表移除元素

目录 链表&#xff08;Linked List&#xff09; 链表的数据结构 单链表 双链表 循环链表 链表的存储方式 删除节点 添加节点 LeetCode之路——203. 移除链表元素 分析&#xff1a; 链表&#xff08;Linked List&#xff09; 链表是一种线性数据结构&#xff0c;用于…

C运算符和控制语句

几乎每一个程序都需要进行运算&#xff0c;对数据进行加工处理&#xff0c;否则程序就没有意义了。要进行运算&#xff0c;就需规定可以使用的运算符。 C语言的运算符范围很宽&#xff0c;把除了控制语句和输人输出以外的几乎所有的基本操作都作为运算符处理。 运算符分类1 除…

Scala第六章节

Scala第六章节 scala总目录 章节目标 掌握类和对象的定义掌握访问修饰符和构造器的用法掌握main方法的实现形式掌握伴生对象的使用掌握定义工具类的案例 1. 类和对象 Scala是一种函数式的面向对象语言, 它也是支持面向对象编程思想的&#xff0c;也有类和对象的概念。我们依…