C++——STL标准模板库——容器详解——vector

一、概念和特性

1、vector:可变大小数组的序列容器——动态数组。

2、vector像数组一样使用连续的空间储存元素,也可以通过下标访问元素。和数组不同的是,当vector容器中空间不足,vector会自动增大储存空间。

3、vector自增空间的原理是,先申请一块更大的储存空间,再将原空间中的数据拷贝到新空间,释放原空间。

4、当vector自增时,因为储存空间的地址已经改变,所以原来的迭代器也失效,需要重新获取。

5、vector不会在插入每个元素时进行自增,重新申请采用对数增长的空间大小,以至于使用尾插法添加元素时为常数时间的复杂度。

6、vector使用尾插法和尾删法增删元素,但其他元素的插入删除时间复杂度较其他序列容器更大大。

7、vector容器中有三个原始迭代器:start——指向储存空间的起始位置,也就是第一个元素;finish——指向已使用空间的末尾位置;end_of_storage——指向已分配储存空间的末尾位置。使用过程中申请的迭代器都是通过这三个原始迭代器获得的。

二、构造函数

vector构造函数有四种。

vector<T> v;        //默认构造函数,定义一个储存T类型元素的向量v

vector<T> v(n);      //定义一个储存了n个T类型元素的向量v,默认值为0

vector<T> v(n,value);//定义一个储存了n个T类型元素的向量v,并将所有元素初始化为value

vector<T> v(v1.begin(),v1.end());        //定义一个能够储存T类型元素的向量,将v1中begin()和end()区间内的元素拷贝到v中。

vector<T> v(v1);     //拷贝构造函数,定义一个容器v将v1中元素拷贝到v中。

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>void myprint(const int value) {cout << value << " ";
}void test() {/*构造函数1,默认构造函数*/vector<int> v1;//尾插法存储数据for (int i = 0; i < 10; i+=2) {v1.push_back(i + 1);}//利用vector容器的数组特性遍历数据for (int i = 0; i < (int)v1.size(); i++) {cout << v1[i] << " ";}cout << endl;/*构造函数2,能够储存10个T类型元素,元素默认值为0*/vector<int> v2(10);//利用迭代器给元素赋值int value = 2;for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++) {*it = (value += 2);}for (int i = 0; i < (int)v2.size(); i++) {cout << v2[i] << " ";}cout << endl;/*构造函数3,能够储存10个T类型元素,并全部初始化成5*/vector<int> v3(10,5);//利用迭代器遍历数据for (vector<int>::iterator it = v3.begin(); it != v3.end(); it++) {cout << *it << " ";}cout << endl;/*构造函数4,申请一个容器v4,将v3中从begin(开)到end(闭)之间的数据拷贝到v4,*/vector<int> v4(v3.begin(), v3.end());//利用STL封装好的算法遍历数据,该函数返回回调函数的返回类型for_each(v4.begin(), v4.end(),myprint);
}
int main() {test();return 0;
}

三、增加函数

void vector<T>::push_back(const T& value);        //向量尾部添加一个元素

terator vector<T>::insert(iterator it,const T& value); //向量中迭代器it指向位置的前面插入数据value

iterator vector<T>::insert(iterator it,int cnt,const T& value);  //向量中迭代器it指向位置的前面插入n个value

iterator vector<T>::insert(iterator it,iterator first,iterator last);//向量中插入同类型容器的一段数据,前闭后开 

insert函数返回指向原来位置的迭代器,原迭代器失效。

四、删除函数

iterator vector<T>::erase(iterator it);        //删除迭代器it指向的元素,返回指向该位置的新迭代器

iterator vector<T>::erase(iterator first,iterator lase);  //删除迭代器[first,last)之间的数据,前闭后开

void vector<T>::pop_back();                   //删除向量尾部一个数据

void vector<T>::clear();                           //清空向量

五、遍历函数

T& vector<T>::at(int index);                //返回下标index位置的数据的引用

T& [int index];                   //向量的数组特性,[]运算符配合下标访问数据,返回该位置元素的引用

T& vector<T>::front();                        //返回向量第一个元素的引用

T& vector<T>::back();                        //返回向量最后一个元素的引用

iterator vector<T>::begin();                //返回指向第一个元素的迭代器

iterator vector<T>::end();                   //返回指向最后一个元素后面位置的迭代器

reverse_iterator vector<T>::rbegin(); //反向迭代器,指向最后一个元素

reverse_iterator vector<T>::rend();    //反向迭代器,指向第一个元素前面一个位置

六、容量函数

bool vector<T>::empty() const;          //判断向量是否为空

int vector<T>::size() const;                //取向量中元素个数

int vector<T>::capacity() const;         //取当前向量的总容量

int vector<T>::max_size() const;       //取该向量允许的最大容量

void vector<T>::reserve(size_t newsize)//预留空间函数,当newsize小于原来向量容量无效。

七、其他函数

void vector<T>::assign(int n,const T& value);        //将n个value赋值给向量

void vector<T>::assign(iterator first,iterator last);//将[fist,last)之间的元素赋值给向量

void vector<T>::assign(initializer_list<T> _list);     //将列表list中的数据赋值给向量  

void vector<T>::swap(vector<T>);                       //交换两个向量所有内容

八、基本用法

1、vector容器不仅能够储存内置数据类型:int、double、char等,还能存储类对象或者结构体。

class Person {
public:Person(string name, int age) :m_Name(name), m_Age(age) {}string m_Name;int m_Age;
};
typedef struct rect {int m_id;int m_length;int m_width;struct rect(int id, int length, int width) :m_id(id), m_length(length), m_width(width) {}
}Rect;
void test() {vector<Person> v;v.push_back(Person("张三", 20));vector<Rect> v1;v1.push_back(Rect(1, 10, 5));cout << v[0].m_Name << " " << v[0].m_Age << endl;cout << v1[0].m_id << " " << v1[0].m_length << " " << v1[0].m_width << endl;
}

2、vector可以储存任意数据类型的vector容器

void myprint(vector<int>& v) {for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {cout << *it;if (it + 1 != v.end()) {cout << " ";}else {cout << endl;}}
}void test() {vector< vector<int> >v;vector<int>v1,v2,v3;for (int i = 0; i < 5; i++) {v1.push_back(i);v2.push_back(i + 2);v3.push_back(i + 4);}v.push_back(v1);v.push_back(v2);v.push_back(v3);for_each(v.begin(), v.end(), myprint);
}

九、注意事项

1、vector容量(capacity)和大小(size)的区别

vector实例化对象时capacity可预先设定,当vector自增时需将原空间中数据赋值到新内存空间,为了避免数据量过大或者频繁发生数据拷贝影响效率,在使用时可申请足够大小容量(capacity)。

vector大小(size)是存储数据的个数,随着插入数据递增,删除数据递减。

2、vector容量(capacity)不会自减

vector的clear()函数清空向量中的数据,是将size设置为0。容量也就是向量所占内存空间并未改变。当需要释放向量所占空间时可以使用swap()函数与一个临时对象进行交换,利用临时对象参与运算后立即销毁的特性释放空间;或者插入一个大括号代码段进行交换,出大括号时自动析构交换过的向量。

void test() {vector<int>v(10);cout << v.size() << " " << v.capacity() << endl;v.clear();cout << v.size() << " " << v.capacity() << endl;//方法1vector<int>().swap(v);//方法2{vector<int>temp;v.swap(temp);}cout << v.size() << " " << v.capacity() << endl;
}

3、vector容器插入数据是插入对象的复制体,而不是插入对象本身,这种机制防止对象的操作影响向量内数据

void test() {vector< vector<int> >v;vector<int>v1,v2,v3;v.push_back(v1);v.push_back(v2);v.push_back(v3);for (int i = 0; i < 5; i++) {v1.push_back(i);v2.push_back(i + 2);v3.push_back(i + 4);}for_each(v.begin(), v.end(), myprint);
}

这个函数输出结果为空,验证了对象操作无法影响到向量内部数据

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

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

相关文章

Linux驱动开发学习笔记4《设备树下的LED驱动实验》

目录 一、设备树LED驱动原理 二、硬件原理图分析 三、实验程序编写 1.修改设备树文件 2.LED 灯驱动程序编写 3.编写测试APP 四、运行测试 1. 编译驱动程序和测试APP &#xff08;1&#xff09; 编译驱动程序 &#xff08;2&#xff09; 编译测试APP ​ 2.运行测试 一、…

ES6之对象新增的方法

Object.is() 严格判断两个值是否相等&#xff0c;与严格比较运算符&#xff08;&#xff09;的行为基本一致&#xff0c;不同之处只有两个&#xff1a;一是0不等于-0&#xff0c;二是NaN等于自身 0 -0 //true NaN NaN // falseObject.is(0, -0) // false Object.is(NaN, Na…

Win11 PS无法拖动文件到任务栏打开

Win11 PS无法拖动文件到任务栏打开 1.软件环境2.问题描述3.解决方法3.1.确保Win11更新到22H2版本以上3.2.确保禁止拖放关闭3.3.修复系统注册表 4.修复效果预览 1.软件环境 Windows11 企业版64位 22H2 Adobe Photoshop 25.2.0 20231101.m.2385 38bb2d3 x64 2.问题描述 很多人在…

SpringBoot配置文件加载的优先级及自定义配置

Spring Boot使用一个非常特殊的PropertySource顺序&#xff0c;旨在允许合理的值重写&#xff0c;越靠前优先级越高。属性按以下顺序考虑&#xff1a; 开发者工具Devtools全局配置参数 在IDEA或Eclipse中&#xff0c;安装并启用Spring Boot Devtools插件。打开项目的Settings…

股票价格预测 | Python实现基于ARIMA和LSTM的股票预测模型(含XGBoost特征重要性衡量)

文章目录 效果一览文章概述模型描述源码设计效果一览 文章概述 Python实现基于ARIMA和LSTM的股票预测模型(Stock-Prediction) Data ExtractionFormatting data for time seriesFeature engineering(Feature Importance using X

【力扣100】2.两数相加

添加链接描述 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Op…

Linux df命令教程:如何有效地查看磁盘空间使用情况(附案例详解和注意事项)

Linux df命令介绍 Linux df命令&#xff08;英文全拼&#xff1a;disk free&#xff09;用于显示目前在Linux系统上的文件系统磁盘使用情况统计。它可以帮助我们了解文件系统的磁盘使用情况&#xff0c;包括已使用的磁盘空间、可用的磁盘空间等。 Linux df命令适用的Linux版本…

信号与线性系统预备训练3——MATLAB软件在信号与系统中的应用初步

信号与线性系统预备训练3——MATLAB软件在信号与系统中的应用初步 The Preparatory training3 of Signals and Linear Systems 对应教材&#xff1a;《信号与线性系统分析&#xff08;第五版&#xff09;》高等教育出版社&#xff0c;吴大正著 一、目的 1.熟悉和回顾MATLAB…

Pycharm第三方库导入失败避坑!

最近遇到了明明安装了 python 第三方库&#xff0c;但是在 pycharm 当中却导入不成功的问题。 使用Pycharm手动安装三方库和自动安装三方库都失败&#xff0c;以及Pycharm终端使用pip命令安装也未解决。网上找各种方法尝试都没成功&#xff0c;原来是一不小心就跳进了虚拟环境…

PASCAL VOC 2012 数据集

PASCAL VOC 2012 数据集 &#xff08;The PASCAL Visual Object Classes 2012,简称PASCAL VOC 2012数据集&#xff09; 背景&#xff1a;PASCAL VOC &#xff08;The PASCAL Visual Object Classes &#xff09;是一个世界级的计算机视觉挑战赛&#xff0c;PASCAL全称&#xf…

C++中的继承(一)

文章目录 前言概念访问限定符基类和派生类的赋值转换继承中的作用域派生类的默认成员函数构造函数 拷贝构造析构函数 继承的其他一些细节 前言 我们之前说过&#xff0c;继承是面向对象的三大特性。 面向对象的三大特性&#xff1a; 封装、继承、多态。 封装在类和对象体现出…

2043杨辉三角(C语言)

目录 一&#xff1a;题目 二&#xff1a;思路分析 三&#xff1a;代码 一&#xff1a;题目 二&#xff1a;思路分析 1.通过杨辉三角&#xff0c;不难发现中间的数等于肩头两个数之和 2.但是当我们的输出结果&#xff0c;与杨辉三角的形式有所不同&#xff0c;但是我们可以找…

Freemarker基本语法与案例讲解

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《SpringBoot》。&#x1f3af;&#x1f3af; &…

python接口自动化测试-unittest-批量用例管理

我们日常项目中的接口测试案例肯定不止一个&#xff0c;当案例越来越多时我们如何管理这些批量案例&#xff1f;如何保证案例不重复&#xff1f;如果案例非常多&#xff08;成百上千&#xff0c;甚至更多&#xff09;时如何保证案例执行的效率&#xff1f;如何做&#xff08;批…

利用n_gram进行情感分析

一、思路 二、关键步骤实现 1、利用tf-idf进行特征提取 详见利用tf-idf对特征进行提取-CSDN博客 2、利用svm进行模型训练 详见​​​​​​​​​​​​​​利用svm进行情感分析-CSDN博客

搞懂这6 个持续集成工具,领先80%测试人!

开发人员喜欢把写的代码当成自己的孩子&#xff0c;他们会被当成艺术品一样呵护。作为家长&#xff0c;总是会认为自己的孩子是最好的&#xff0c;也会尽全力给自己的孩子最好的&#xff0c;就算有时候会超出自己的能力范围。 最终&#xff0c;孩子会走出去&#xff0c;和其他…

HarmonyOS云开发基础认证考试满分答案(100分)【全网最全-不断更新】【鸿蒙专栏-29】

系列文章&#xff1a; HarmonyOS应用开发者基础认证满分答案&#xff08;100分&#xff09; HarmonyOS应用开发者基础认证【闯关习题 满分答案】 HarmonyOS应用开发者高级认证满分答案&#xff08;100分&#xff09; HarmonyOS云开发基础认证满分答案&#xff08;100分&#xf…

C++设计模式-Builder 构建器

通过“对象创建” 模式绕开new&#xff0c;来避免对象创建&#xff08;new&#xff09;过程中所导致的紧耦合&#xff08;依赖具体类&#xff09;&#xff0c;从而支持对象创建的稳定。它是接口抽象之后的第一步工作。 一、动机 在软件系统中&#xff0c;有时候面临着“一个复…

Spark基础入门

spark基础入门 环境搭建 localstandlonespark ha spark code spark corespark sqlspark streaming 环境搭建 准备工作 创建安装目录 mkdir /opt/soft cd /opt/soft下载scala wget https://downloads.lightbend.com/scala/2.13.12/scala-2.13.12.tgz -P /opt/soft解压scala…

网络安全应急响应之事件分类

文章目录 一、描述二、有害程序事件1、计算机病毒事件2、蠕虫事件3、特洛伊木马事件4、僵尸网络事件5、混合攻击程序事件6、网页内嵌恶意代码事件7、其它有害程序事件 二、网络攻击事件1、拒绝服务攻击事件2、后门攻击事件3、漏洞攻击事件4、网络扫描窃听事件5、网络钓鱼事件6、…