【C++】STL的vector容器

news2024/11/26 10:02:52

目录

2、vector容器

1.1模板实例化

1.2定义与初始化vector对象

2.1vector构造函数

2.2vector赋值操作

2.2vector的容量和大小

2.4vector的插入

2.5vector的删除

2.6vector数据存取

2.7vector互换容器

2.8vector预留空间


2、vector容器

vector是C++最常用的容器之一,其本质是动态增长的数组。而vector是C++六大组件之一的容器,容器时存放数据的一些数据结构。vector比常用数组的好处在于,我们可以动态的改变大小,并且无需预先分配指定的大小。

vector的尾部插入和删除的效率很高,达到了常数级别的时间复杂度。并且支持随机访问。不过对于不在末尾的插入删除,效率较低。

vector容器的功能和数组非常相似,使用时可以把它看成一个数组。

vector容器和普通数组的其区别:

  1. 数组是静态的,长度不可改变,而vector可以动态扩展。增加长度
  2. 数组内数据通常存储在栈上,而vector中数据存储在堆上

动态扩展:动态扩展并不是原空间之后续接新空间,而是找到比原来更大的内存空间,将原数据拷贝刀新空间,释放原空间。

使用vector容器之前一定要包含头文件

#include <vector>

1.1模板实例化

想要将模板示例化成具体的类,需要我们提供一些额外的信息指定到底成什么类,提供信息的方式是:在模板名字后加一对尖括号,在括号内填入信息。

vector<int> s1              //s1中保存int类型的对象
vector<string> s2           //s2中保存string类型的对象
vector<s_item> s3           //s3中保存s_item类的对象
vector<vector<string>> s4   //该向量的元素是vector对象

注意:

  1. vector是模板而非类型,其生成的类型必须包含vector中元素类型,如vector
  2. 引用不是对象,所以不存在包含引用的vector
  3. 一些老式编译器无法识别vector>,只能识别vector >(后两个尖括号间有空格)

1.2定义与初始化vector对象

定义常用方法:

最常见的方式是先定义一个空的vector,然后运行时获取元素值再逐一添加

如果要把一个vector容器拷贝到另一个里,那么两个容器对象类型必须一致,此时新容器是原容器的副本

vector<int> s1;
//添加一些元素
vector<int> s2(s1)       //把s1中元素拷贝到s2
vector<int> s3=s1        //把s1中元素拷贝到s3
vector<string> s4(s2)    //错误,对象不一致

列表初始化vector对象

C++11新标准还提供了另外一种为vector对象的元素赋初值的方法,即列表初始化。此时,用花括号括起来的0个或多个初始元素值被赋给vector对象:

vector<string> s={"a","aa","aaa"};

此时,s1中有三个元素a aa aaa

如果提供的是初始值,那么只能放在花括号中

vector<string> s={"a","aa","aaa"};    //正确
vector<string> s=("a","aa","aaa");    //错误

 创建指定数量的元素

vector<int> s=(10,1);             //创建10个1
vector<string> s=(10,“hi”);    //创建是个hi

值初始化

通常情况下,可以只提供vector对象容纳的元素数量而不用略去初始值。此时库会创建一个值初始化的元素初值,并把它赋给容器中的所有元素。这个初值由vector对象中元素的类型决定。

vector<int> s=(10);             //10个0
vector<string> s=(10);        //10个空string对象

元素个数与初始化值

在某些情况下,初始化的真实含义依赖于传递初始值时用的是花括号还是圆括号。例如,用一个整数来初始化vector时,整数的含义可能是vector对象的容量也可能是元素的值。类似的,用两个整数来初始化vector时,这两个整数可能一个是vector对象的容量,另一个是元素的初值,也可能它们是容量为2的vector对象中两个元素的初值。通过使用花括号或圆括号可以区分上述这些含义:

vector<int> v1 (10);            // v1有10个元素,每个的值都是0
vector<int> V2{10};             // v2有1个元素,该元素的值是10
vector<int> v3(10,1);          //v3有10个元素,每个的值都是1
vector<int> v4{10,1};           //v4有2个元素,值分别是10和1

如果初始化时使用了花括号的形式但是提供的值又不能用来列表初始化,就要考虑用这样的值来构造vector对象了

vector<string> v5{ "hi"};        //列表初始化:v5有一个元素
vector<string> v6("hi");         //错误:不能使用字符串字面值构建vector对象
vector<string> V7{10};           //v7有10个默认初始化的元素
vector<string> V8{10,"hi"};      // v8有10个值为"hi"的元素

可以这么理解:当内部元素类型不一致时,花括号初始化默认先按赋值处理,当格式合适时,按小括号处理。

2.1vector构造函数

vector<T> v;                       //采用模板实现类实现,默认构造函数
vector(v.begin(), v.end());        //将v[begin(), end())区间中的元素拷贝给本身。
vector(n, elem);                   //构造函数将n个elem拷贝给本身。
vector(const vector &vec);         //拷贝构造函数。

测试案例代码:
void printVector(vector<int>& v) 
{

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


int main(void)
{
        vector<int> v1; //无参构造
        for (int i = 0; i < 10; i++)
        {
            v1.push_back(i);
        }
        printVector(v1);
    
        vector<int> v2(v1.begin(), v1.end());
        printVector(v2);
        
        vector<int> v3(10, 100);
        printVector(v3);
    
        vector<int> v4(v3);
        printVector(v4);
    
        return 0;
}

2.2vector赋值操作

函数功能:给vector容器进行赋值

vector& operator=(const vector &vec);    //重载等号操作符
assign(beg, end);                        //将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);                         //将n个elem拷贝赋值给本身

测试案例代码:
int main(void)
{
        vector<int> v1; //无参构造
        for (int i = 0; i < 10; i++)
        {
            v1.push_back(i);
        }
        printVector(v1);
    
        vector<int>v2;
        v2 = v1;
        printVector(v2);
    
        vector<int>v3;
        v3.assign(v1.begin(), v1.end());
        printVector(v3);
    
        vector<int>v4;
        v4.assign(10, 100);
        printVector(v4);
    
        return 0;
}

2.2vector的容量和大小

函数功能:对vector容器的容量和大小操作

empty();               //判断容器是否为空
capacity();            //容器的容量
size();                //返回容器中元素的个数
resize(int num);       //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
  ​                     //如果容器变短,则末尾超出容器长度的元素被删除。
resize(int num, elem)  //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。
                       //如果容器变短,则末尾超出容器长度的元素被删除
 
测试案例代码:
int main(void)
{
        vector<int> v1;
        for (int i = 0; i < 10; i++)
        {
            v1.push_back(i);
        }
        printVector(v1);
        if (v1.empty())
        {
            cout << "v1为空" << endl;
        }
        else
        {
            cout << "v1不为空" << endl;
            cout << "v1的容量 = " << v1.capacity() << endl;
            cout << "v1的大小 = " << v1.size() << endl;
        }
    
        //resize 重新指定大小 ,若指定的更大,默认用0填充新位置,可以利用重载版本替换默认填充
        v1.resize(15, 10);
        printVector(v1);
    
        //resize 重新指定大小 ,若指定的更小,超出部分元素被删除
        v1.resize(5);
        printVector(v1);
    
        return 0;
}

2.4vector的插入

函数功能:对vector容器进行插入操作

push_back(ele);                                 //尾部插入元素ele
insert(const_iterator pos, ele);                //迭代器指向位置pos插入元素ele
insert(const_iterator pos, int count,ele);      //迭代器指向位置pos插入count个元素ele

测试案例代码:
 int main(void)
{
    vector<int> v1;
        //尾插
        v1.push_back(10);
        v1.push_back(20);
        v1.push_back(30);
        v1.push_back(40);
        v1.push_back(50);
        printVector(v1);

        //插入
        v1.insert(v1.begin(), 100);
        printVector(v1);
    
        v1.insert(v1.begin(), 2, 1000);
        printVector(v1);
    
        return 0;
} 

2.5vector的删除

函数功能:对vector容器进行删除操作

pop_back();                                       //删除最后一个元素
erase(const_iterator pos)                         //删除迭代器指向的元素
erase(const_iterator start, const_iterator end);  //删除迭代器从start到end之间的元素
clear();                                          //删除容器中所有元素

测试案例代码:
int main(void)
{
        vector<int> v1;
        //尾插
        v1.push_back(10);
        v1.push_back(20);
        v1.push_back(30);
        v1.push_back(40);
        v1.push_back(50);
        printVector(v1);
    
        //尾删
        v1.pop_back();
        printVector(v1);        

        //删除
        v1.erase(v1.begin());
        printVector(v1);
    
        //清空
        v1.erase(v1.begin(), v1.end());
        v1.clear();
        printVector(v1);
    
        return 0;
}

2.6vector数据存取

函数功能:给vector容器进行存取操作

at(int idx);      //返回索引idx所指的数据
operator[];       //返回索引idx所指的数据
front();          //返回容器中第一个数据元素
back();           //返回容器中最后一个数据元素

测试案例代码:
int main(void)
{
        vector<int>v1;
        for (int i = 0; i < 10; i++)
        {
            v1.push_back(i);
        }
    
        for (int i = 0; i < v1.size(); i++)
        {
            cout << v1[i] << " ";
        }
        cout << endl;
    
        for (int i = 0; i < v1.size(); i++)
        {
            cout << v1.at(i) << " ";
        }
        cout << endl;
    
        cout << "v1的第一个元素为: " << v1.front() << endl;
        cout << "v1的最后一个元素为: " << v1.back() << endl;
     
       return 0;
}

2.7vector互换容器

函数功能:实现两个vector容器内元素进行互换

swap(vec);  // 将vec与本身的元素互换

测试案例代码:
int main(void)
{
    vector<int>v1;
        for (int i = 0; i < 10; i++)
        {
            v1.push_back(i);
        }
        printVector(v1);
    
        vector<int>v2;
        for (int i = 10; i > 0; i--)
        {
            v2.push_back(i);
        }
        printVector(v2);
    
        //互换容器
        cout << "互换后" << endl;
        v1.swap(v2);
        printVector(v1);
        printVector(v2);
    
        return 0;
}  

2.8vector预留空间

函数功能:减少vector在动态扩展容量时的扩展次数

reserve(int len);    //容器预留len个元素长度,预留位置不初始化,元素不可访问

测试案例代码:
int main(void)
{
        vector<int> v;
    
        //预留空间
        v.reserve(100000);
    
        int num = 0;
        int* p = NULL;
        for (int i = 0; i < 100000; i++) 
        {
            v.push_back(i);
            if (p != &v[0]) {
                p = &v[0];
                num++;
            }
        }
    
        cout << "num:" << num << endl;
    
        return 0;
}

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

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

相关文章

深度学习(神经网络)

文章目录 神经网络历史形式神经元模型&#xff08;M-P模型&#xff09;感知器多层感知器 误差反向传播算法误差函数和激活函数误差函数二次代价函数交叉熵代价函数 激活函数sigmoid函数RELU函数 似然函数softmax函数 随机梯度下降法批量学习方法在线学习小批量梯度下降法 学习率…

<Linux开发>驱动开发 -之-阻塞、非阻塞IO和异步通知

&#xff1c;Linux开发&#xff1e;驱动开发 -之-阻塞、非阻塞IO和异步通知 交叉编译环境搭建&#xff1a; &#xff1c;Linux开发&#xff1e; linux开发工具-之-交叉编译环境搭建 uboot移植可参考以下&#xff1a; &#xff1c;Linux开发&#xff1e; -之-系统移植 uboot移…

easyui01(基本布局)

一.概述 1.What&#xff1f; jQuery EasyUI是一组基于jQuery的UI插件集合体&#xff0c;能帮助web开发者更轻松的打造出功能丰富并且美观的UI界面 2.Why&#xff1f; ①.使用easyui 不需要写很多代码&#xff0c;只需要编写一些简单 HTML 标记&#xff0c;就可以定义用户界…

Java优先级队列源码分析

先导课程&#xff1a;二叉堆学习 优先级队列 1. Priority Queue 优先级队列&#xff08;Priority Queue&#xff09;也是队列 普通队列按照FIFO原则&#xff0c;也就是先进先出优先级队列按照优先级高低进行出队&#xff0c;比如将优先级最高的元素作为队头优先出队 基本接口和…

Vue3中Composition 其他一些API

一、 Reactive判断的API 1. isProxy 检查对象是否由reactive或者readonly创建的proxy &#xff0c;返回一个布尔值 <script setup> import { reactive, readonly, isProxy } from vuelet foo readonly({ name: WFT1 }) // 其中的属性不可修改let bar reactive({ n…

DeepSpeed结合Megatron-LM训练GPT2模型笔记(上)

文章目录 0x0. 前言0x1. Megatron使用单卡训练GPT2依赖安装准备训练数据训练详细流程和踩坑 0x2. Megatron使用单卡预测训练好的GPT2模型0x3. 参数量和显存估计参数量估计训练显存占用估计 0x4. Megatron使用多卡训练GPT2模型2卡数据并行2卡模型并行 0x5. 总结 0x0. 前言 本文…

【V4L2】 v4l2框架分析之v4l2_subdev

文章目录 一、v4l2_subdev简介二、初始化v4l2_subdev三、注册/注销subdev四、异步注册子设备 一、v4l2_subdev简介 相关源码文件&#xff1a; /include/media/v4l2-subdev.h/drivers/media/v4l2-core/v4l2-subdev.c 在linux内核中&#xff0c;许多驱动程序需要与子设备通信&…

【嵌入式linux】spi驱动加载后probe函数未执行的问题

【嵌入式linux】spi驱动加载后probe函数未执行的问题 问题描述解决办法 问题描述 嵌入式linux平台下的spi分为设备、总线和驱动&#xff0c;一般半导体原厂已经实现好了spi设备和总线的相关代码&#xff0c;开发者只需根据实际使用情况修改设备树以及编写驱动部分的代码即可。…

Android进阶 四大组件的工作过程(四):ContentProvider的工作过程

Android进阶 四大组件的工作工程&#xff08;四&#xff09;&#xff1a;ContentProvider的工作过程 导语 本篇是介绍四大组件的最后一篇文章&#xff0c;前三篇文章里我们已经介绍了Activity&#xff0c;Service以及Broadcast的工作流程&#xff0c;那么这篇文章我们就来介绍…

【数据结构与算法分析】一文搞定插入排序、交换排序、简单选择排序、合并排序的代码实现并给出详细讲解

文章目录 排序相关的基本概念排序算法及其实现插入排序直接插入排序折半插入排序希尔排序 交换排序冒泡排序快速排序 合并排序归并排序简单选择排序 算法比较 排序相关的基本概念 排序&#xff1a;将数组中所有元素按照某一顺序(从小到大或从大到小)重新排列的过程。排序算法的…

DJ2-5 内容分发网络 CDN

目录 单一的大规模数据中心 内容分发网络 CDN 单一的大规模数据中心 存在三个问题&#xff1a; ① 如果客户远离数据中心&#xff0c;服务器到客户的分组将跨越许多通信链路并很可能通过许多 ISP&#xff0c;给用户带来恼人的时延。 ② 流行的视频很可能经过相同的通信链路…

[C++11] 智能指针

长路漫漫&#xff0c;唯剑作伴。 目录 长路漫漫&#xff0c;唯剑作伴。 为什么需要智能指针 RAII 使用RAII思想管理内存 重载 * 和-> 总结一下智能指针的原理&#xff1a; C的智能指针和拷贝问题 auto_ptr (C98) ​编辑 auto_ptr的实现原理…

EmGUCV中类函数 FastFeatureDetector使用详解

FastFeatureDetector Class 释义&#xff1a;FAST&#xff08;加速检测特&#xff09;关键点检测器&#xff0c;源自 E. Rosten ("Machine learning for high-speed corner detection, 2006). 继承关系&#xff1a;Emgu.CV.Features2D.FastFeatureDetector 派生&#xff…

记录好项目D5

记录好项目 你好呀&#xff0c;这里是我专门记录一下从某些地方收集起来的项目&#xff0c;对项目修改&#xff0c;进行添砖加瓦&#xff0c;变成自己的闪亮项目。修修补补也可以成为毕设哦 本次的项目是 商品信息管理系统 技术栈&#xff1a;SpringBoot Mybatis Thymelea…

MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性

\ &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭…

细谈容器化技术实现原理--以Docker为例

目录 一、Docker解决了什么 二、容器的发展过程 三、容器基础 3.1. 容器实现的原理&#xff1a; ⚠️原理详解&#xff1a; 3.1.1. Namespace 3.1.2. Cgroups 3.1.3. chroot 四、Volume 4.1. Docker是如何做到把一个宿主机上的目录或者文件&#xff0c;挂载到容器里面…

4. 数组更新检测

4.1 v-for更新监测 当v-for遍历的目标结构改变, Vue触发v-for的更新 情况1: 数组翻转 情况2: 数组截取 情况3: 更新值 口诀: 数组变更方法, 就会导致v-for更新, 页面更新 数组非变更方法, 返回新数组, 就不会导致v-for更新, 可采用覆盖数组或this.$set() 这些方法会触发数组改…

基于深度学习的高精度鸽子检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度鸽子检测识别系统可用于日常生活中或野外来检测与定位鸽子目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的鸽子目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型…

XSS注入——反射性XSS

xss注入的攻击步骤&#xff1a; 1.查找可能存在的注入点&#xff08;搜索框&#xff0c;留言板&#xff0c;注册&#xff09; 2.观察输出显示位置&#xff1a; html&#xff1a; 尖括号外部&#xff0c; 尖括号内部: 引号内部》闭合&#xff0…

Django | 基于pycharm的django配置52张全流程截图,红星给你一步一步的男妈妈式教学

演示版本&#xff1a;【windows系统】python3.10pycharm2023.1.2django4.2.2 &#xff08;本教程全程在虚拟机中演示&#xff0c;读者无需配置虚拟机&#xff0c;直接按教程安装即可&#xff09; 目录 1.搞到必要的安装包 2.事先准备 3.安装chrome浏览器&#xff08;也可以…