【十二】【C++】vector用法的探究

news2024/11/19 4:39:42

vector类创建对象

 
/*vector类创建对象*/
#if 1
#define _CRT_SECURE_NO_WARNINGS
 #include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <crtdbg.h>


class Date {
    public:
        Date(int year = 1900, int month = 1, int day = 1)
            : _year(year)
            , _month(month)
            , _day(day)
        {}

    private:
        int _year;
        int _month;
        int _day;
 };

//创建对象
void TestVector1() {
    vector<int> v1(10, 5);
    vector<int> v2(10);
    vector<Date> v3(10);
    vector<int> v4{ 1, 2, 3 };  // C++11
    
    vector<int> vec; // 创建一个空的int类型vector
    vector<int> vec2(10); // 创建一个包含10个初始化为0的int元素的vector
    vector<int> vec3(10, 1); // 创建一个包含10个初始化为1的int元素的vector
    vector<int> vec4{1, 2, 3, 4, 5}; // 列表初始化
    vector<int> vec5(vec4.begin(), vec4.end()); // 范围初始化
    vector<int> vec6(vec4); // 拷贝初始化

}
#endif

进入调试可以看到变量已经创建成功,里面的具体情况如下图所示。

vector类capacity的扩容规律

 
/*vector类capacity的扩容规律*/
#if 0
/*
 1. vs中:vector是按照1.5倍方式扩容  linux下是按照2倍方式扩容
 2. 放元素时如果已经知道大概要放多少个元素,可以提前将空间设置好
 避免:一边插入一边扩容效率低下
 */
#define _CRT_SECURE_NO_WARNINGS
 #include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <crtdbg.h>

void TestVector2() {
    vector<int> v;
    v.reserve(10);
//    v.reserve(100);提前分配空间
    size_t cap = v.capacity();

    for (size_t i = 0; i < 100; ++i) {
        v.push_back(i);
        if (cap != v.capacity()) {
            cap = v.capacity();
            cout << cap << endl;
        }
    }
 }
int main(){
    TestVector2();
 }
#endif

这段代码演示了如何在C++中使用std::vector,特别关注其动态扩容的行为,并提供了一个实用的建议,即如果预先知道将要存储的元素数量,可以使用reserve方法来提前分配足够的空间,以避免在添加元素时频繁的动态扩容操作,从而提高效率。

代码解释

vector<int> v; 创建了一个名为v的空vector,用于存储int类型的元素。

v.reserve(10); 使用reserve方法为v预先分配足够的空间,以存储至少10个int类型的元素。这是基于先前的建议:如果已知将要存储的元素数量,预先分配空间可以提高效率。

size_t cap = v.capacity(); 初始化cap变量,用于存储v当前的容量。

接下来的循环中,通过push_back方法向v中添加了100个整数(从0到99)。每次添加元素后,都会检查v的容量是否发生变化:

如果容量发生变化(意味着vector进行了扩容),则更新cap变量,并输出新的容量值。

扩容机制

代码中的注释提到了std::vector扩容机制的平台相关性:

在Visual Studio(VS)环境下,std::vector通常按照1.5倍的方式扩容。

在Linux环境下,std::vector可能按照2倍的方式扩容。

这种差异意味着在不同的平台上,相同的代码可能会有不同的内存使用和性能表现。

vector访问元素的方式

 
/*vector访问元素的方式*/
#if 1
#define _CRT_SECURE_NO_WARNINGS
 #include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <crtdbg.h>
void TestVector3() {
    vector<int> v{ 1, 2, 3, 4, 5 };
    cout << v.front() << endl;
    cout << v.back() << endl;
    v.front() = 10;
    v.back() = 50;

    cout << v[13] << endl;
    cout << v.at(14) << endl;

    v.clear();
    cout << v.front() << endl;
    cout << v.back() << endl;
 }
int main(){
    TestVector3();
 }
#endif

注释16、17、19行的代码,运行代码。

v.front()返回v对象第一个元素,v.back()返回v对象最后一个元素。

注释19行的代码,运行代码。

v[13]访问下标为13的元素,越界访问,但是不会检查范围。

v.at(14)访问下标为14的元素,越界访问,会报错,会检查范围,报错后,后面的代码不会再运行。

assign用法,用数组代替vector内容

 
/*已经存在的vector对象,用一个数组代替vector内容*/
#if 1
#define _CRT_SECURE_NO_WARNINGS
 #include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <crtdbg.h>

void TestVector4() {
    vector<int> v(3, 5);

    int array[] = { 1, 2, 3, 4, 5 };
//     v = array;  编译失败

    v.clear();
    for (int i = 0; i <(int)(sizeof(array) / sizeof(array[0])); ++i)
    {
         v[i] = array[i];   // 越界
         v.push_back(array[i]);
    }

    v.assign(array, array + sizeof(array) / sizeof(array[0]));

     v.assign(10, 5);
}
int main(){
    TestVector4();
 }
#endif

注释20,23,25行代码,运行代码。

调试代码运行到结尾,发现v对象中lengthcapacity没有变化,原因很简单,我们只是简单修改v对象对应位置的值,但是v对象还有lengthcapacity成员变量需要改变。

注释19,23,25行代码,运行代码。

注释17-21,25行代码,运行代码。

v.assign(array, array + sizeof(array) / sizeof(array[0]));array数组的0位置到结尾,代替v里面的内容。

注释17-21,23行代码,运行代码。

vec4.assign(5, 10); 将vector中的内容替换为5个10

vector的插入操作insert探究

 
/*vector插入操作insert探究*/
#if 1
#define _CRT_SECURE_NO_WARNINGS
 #include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <crtdbg.h>
void TestVector5() {
    vector<int> v{ 1, 2, 3 };
    v.insert(v.begin(), 0);
    v.insert(v.end(), 4);

    // 0 1 2 3 4
    // 在1号元素的位置插入10个5
    v.insert(v.begin() + 1, 10, 5);

    // 要在data元素所在的位置插入array数组
    int data;
    cin >> data;

    int array[] = { 10, 20, 30 };
//    vector<int>::iterator pos = find(v.begin(), v.end(), data);
    auto pos = find(v.begin(), v.end(), data);
    if (pos != v.end()) {
        v.insert(pos, array, array + sizeof(array) / sizeof(array[0]));
    }
    
}
int main() {
    TestVector5();
 }
#endif

小结论:

迭代器begin()指向第一个元素,end()指向最后一个元素后面一个位置。

插入操作传参表示位置,传的都是迭代器。

都是在迭代器位置前面插入数据。

vector的删除操作erase探究

 
/*vector的删除erase操作探究*/
#if 1
#define _CRT_SECURE_NO_WARNINGS
 #include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <crtdbg.h>
void TestVector6() {
    vector<int> v{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };

    v.erase(v.begin());
    v.erase(v.begin(), v.begin() + 5);
    v.erase(v.begin(), v.end());    // clear()
}
int main(){
    TestVector6();
 }
#endif

小结论:

删除多个元素,区间是左开右闭。

vector的交换操作swap探究

 
/*swap交换操作探究*/
#if 1
#define _CRT_SECURE_NO_WARNINGS
 #include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <crtdbg.h>
void TestVector7() {
    vector<int> v1{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    vector<int> v2{ 12, 23, 34 };
    swap(v1, v2);

    v1.swap(v2);
 }
int main(){
    TestVector7();
 }
#endif

vector的访问操作探究

 
/*vector访问操作探究*/
#if 1
#define _CRT_SECURE_NO_WARNINGS
 #include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <crtdbg.h>
void TestVector8() {
    vector<int> v1{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };

    for (size_t i = 0; i < v1.size(); ++i) {
        cout << v1[i] << " ";
    }
    cout << endl;

    for (auto e : v1) {
        cout << e << " ";
    }
    cout << endl;

    auto it = v1.begin();
    while (it != v1.end()) {
        cout << *it << " ";
        ++it;
    }
    cout << endl;

    sort(v1.begin(), v1.end());
 }
int main(){
    TestVector8();
 }
#endif

访问vector的三种方式:

  1. operator[]访问

  2. 范围for

  3. 迭代器

vector的迭代器失效探究

 
// 迭代器失效
#if 1
#define _CRT_SECURE_NO_WARNINGS
 #include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <crtdbg.h>

void TestVector9() {
    vector<int> v{ 1, 2, 3, 4, 5 };
    // it指向的是v的当前的起始位置
    auto it = v.begin();

    // 扩容之后,可能会导致扩容
    // 开辟新空间  拷贝元素  释放旧空间
    v.push_back(6);

    // it指向v之前的空间已经被释放了,it指向的空间就是非法的
    // it的迭代器已经失效了

    // 解决迭代器失效的方法:
    it = v.begin();
    while (it != v.end()) {
        cout << *it << " ";
        ++it;
    }
    cout << endl;
 }
int main(){
    TestVector9();
 }
#endif

扩容操作,开辟新的空间,而老迭代器还指向旧的空间,此时迭代器指向的空间是已经被消灭的空间,解决这个问题就必须重新让迭代器指向新空间的位置。

vector删除操作后返回下一个元素的迭代器位置

 
/*vector删除操作后返回下一个位置的迭代器位置*/
#if 1
#define _CRT_SECURE_NO_WARNINGS
 #include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <crtdbg.h>

void TestVector10() {
    vector<int> v{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    auto it = v.begin();
    while (it != v.end()) {
        if (*it & 1 || *it == 0)
            it = v.erase(it);
        else
            ++it;
    }

 }
int main() {
    TestVector10();
 }

#endif

用vector创建二维数组

 
/*用vector创建二维数组*/
#if 1
/*
 用vector创建二维数组:
 1. 矩阵
 a. 所有元素都相同
 b. 元素不同
 2. 每行元素个数不同---比如杨慧三角
 */

#define _CRT_SECURE_NO_WARNINGS
 #include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <crtdbg.h>
// a. 所有元素都相同
void TestVector11() {
    
//     5行10列  所有元素都是8
 //    1.依次尾插
    vector<vector<int>> v1;
    v1.resize(5);
    for (int i = 0; i < 5; ++i)
    {
        for (int j = 0; j < 10; ++j)
        {
            v1[i].push_back(8);
        }
    }
//    2.无参构造,resize
     vector<vector<int>> v2;
     v2.resize(5, vector<int>(10, 8));
//    3.vector构造函数嵌套
    vector<vector<int>> v3(5, vector<int>(10, 8));
 }
int main(){
    TestVector11();
 }
#endif

vector<vector<int>> v3(5, vector<int>(10, 8));创建对象v3,元素数据类型是vector<int>类型,元素个数有五个,对这五个元素进行初始化,全部初始化为vector<int>(10,8),匿名对象构造函数。

常用于创建矩阵

 
/*用vector创建二维数组---杨慧三角*/
#if 1
#define _CRT_SECURE_NO_WARNINGS
 #include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <crtdbg.h>
// 2. 每行元素个数不同---比如杨慧三角
void TestVector12() {
    int n;
    cin >> n;

    // vector(size_t n, const T& val = T())
    // vector<vector<int>> vv(n, vector<int>());
    vector<vector<int>> vv(n);
    for (size_t i = 0; i < vv.size(); ++i) {
        vv[i].resize(i + 1, 1);
    }

    /*
    0:1
    1:1  1
    2:1  2  1
    3:1  3  3  1
    4:1  4  6  4  1
    。。。
    */
    for (size_t i = 2; i < vv.size(); ++i) {
        for (size_t j = 1; j < vv[i].size() - 1; ++j) {
            vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
        }
    }
 }
int main(){
    TestVector12();
 }

使用reserve、resize的探究

 
/*使用reserve、resize的小技巧*/
#if 1
#define _CRT_SECURE_NO_WARNINGS
 #include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <crtdbg.h>

void TestVector13() {
    vector<int> v2;
    v2.reserve(10);
    v2[0] = 1;
    
     vector<int> v3;
    v3.resize(10);
    v3[0] = 1;
    
     vector<int> v1;
    v1[0] = 1;


 }
int main() {
    TestVector13();
    return 0;
 }
#endif

capacity容量,已经开辟的空间大小,length使用的空间大小。如果通过无参的构造函数创建v1lengthcapacity都是0,此时访问元素并修改会报错,因为此时v1还没有开辟空间。

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。

同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。

谢谢您的支持,期待与您在下一篇文章中再次相遇!

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

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

相关文章

Compose之Slider全面解析

JetPack Compose系列&#xff08;14&#xff09;—Slider Slider&#xff0c;即拖动条&#xff0c;默认包含了一个滑块和一个滑动轨道。允许用户在一个数值范围内进行选择。 按照惯例&#xff0c;先观察其构造函数&#xff1a; Composable fun Slider(value: Float,onValueCh…

#Z0463. 巡逻1

Description 在一个地区中有 n 个村庄&#xff0c;编号为 1, 2, ..., n。有 n – 1 条道路连接着这些村 庄&#xff0c;每条道路刚好连接两个村庄&#xff0c;从任何一个村庄&#xff0c;都可以通过这些道路到达其 他任一个村庄。每条道路的长度均为 1 个单位。 为保证该地区的…

了解数据治理体系化建模

目录 一、走近数据体系化建模 &#xff08;一&#xff09;软件体系化建模 &#xff08;二&#xff09;数据体系化建模 二、数据体系化建模实践 三、数据管理考量思考 &#xff08;一&#xff09;数据质量方面的考量 &#xff08;二&#xff09;数据安全、合规方面的考量…

攻防世界 CTF Web方向 引导模式-难度1 —— 11-20题 wp精讲

PHP2 题目描述: 暂无 根据dirsearch的结果&#xff0c;只有index.php存在&#xff0c;里面也什么都没有 index.phps存在源码泄露&#xff0c;访问index.phps 由获取的代码可知&#xff0c;需要url解码(urldecode )后验证id为admin则通过 网页工具不能直接对字母进行url编码 …

CSS 2D转换 3D动画 3D转换

目录 2D转换(transform): 移动translate: 旋转rotate: 缩放scale&#xff1a; CSS3动画&#xff08;transform&#xff09;&#xff1a; 动画常用的属性&#xff1a; 将长图片利用盒子实现动画的效果&#xff1a; 3D转换&#xff1a; 透视perspective&#xff1a; 旋转r…

【动态规划】【字符串】1092. 最短公共超序列

作者推荐 【动态规划】【前缀和】【C算法】LCP 57. 打地鼠 本文涉及知识点 动态规划汇总 LeetCode1092最短公共超序列 给你两个字符串 str1 和 str2&#xff0c;返回同时以 str1 和 str2 作为 子序列 的最短字符串。如果答案不止一个&#xff0c;则可以返回满足条件的 任意…

C++数据类型、变量常量

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 大家新年快乐&#xff0c;今天我们来学习C的数据类型&#xff0c;变量常量。 文章目录 1.数据类型的概念与思想 1.1基本数据类型 1.2复合数据类型 1.3类型修饰符 1.4类型转换 1.4.1static_cast 1.4.2…

【机器学习】数据清洗之处理缺失点

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步…

腾讯云4核8G服务器最大能承载多少用户在线?12M带宽

腾讯云轻量4核8G12M轻量应用服务器支持多少人同时在线&#xff1f;通用型-4核8G-180G-2000G&#xff0c;2000GB月流量&#xff0c;系统盘为180GB SSD盘&#xff0c;12M公网带宽&#xff0c;下载速度峰值为1536KB/s&#xff0c;即1.5M/秒&#xff0c;假设网站内页平均大小为60KB…

HTML5和CSS3强化知识总结

HTML5的新特性 HTML5的新增特性主要是针对于以前的不足&#xff0c;增一些新的标签、新的表单和新的表单属性等。这些新特性都有兼容性问题&#xff0c;基本是IE9以上版本的浏览器才支持&#xff0c;如果不考虑兼容性问题&#xff0c;可以大量使用这些新特性。 HTML5新增的语义…

创建自己的系统创富法则,做个轻松赚钱的甩手掌柜

一、教程描述 本套系统创富教程&#xff0c;大小744.80M&#xff0c;共有28个文件。 二、教程目录 01.走遍全球四十多个国家&#xff0c;我才发现赚钱的本质如此雷同.mp4 02.靠工资技术赚钱太慢&#xff0c;想赚到自己的第一个一百万的方法是&#xff1f;.mp4 03.不服暴发…

uv机器电机方向极性

爱普生主板设置X、Y 电机方向极性&#xff1a;请根据实际情况设置&#xff0c;开机初始化时如果电机运动方向反了则修改此极性。 理光主板设置X、Y 电机方向极性

研究多态恶意软件,探讨网络安全与AI

前言 近期ChatGPT火遍全球&#xff0c;AI技术被应用到了全球各行各业当中&#xff0c;国内外各大厂商也开始推出自己的ChatGPT&#xff0c;笔者所在公司在前段时间也推出了自研的安全GPT&#xff0c;AI技术在网络安全行业得到了很多的应用&#xff0c;不管是网络安全研究人员、…

【51单片机】自定义静态数码管显示(设计思路&代码演示)

前言 大家好吖&#xff0c;欢迎来到 YY 滴单片机系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 主要内容含&#xff1a; 本章节内容为【实现动静态数码管】项目的第三个模块完整章节&#xff1a;传送门 欢迎订阅 YY滴C专栏&#xff01;更多干货持…

【资料分享】基于单片机大气压监测报警系统电路方案设计、基于飞思卡尔的无人坚守点滴监控自动控制系统设计(程序,原理图,pcb,文档)

基于单片机大气压监测报警系统电路方案设计 功能&#xff1a;实现的是大气压检测报警系统&#xff0c;可以通过传感器实时检测当前大气压值&#xff0c;可以设定大气压正常范围&#xff0c;当超过设定范围进行报警提示。 资料&#xff1a;protues仿真&#xff0c;程序&#x…

SpringCloud-高级篇(十九)

我们已经学过使用 SpringAMQP去收和发消息&#xff0c;但是发和收消息是只是MQ最基本的功能了&#xff0c;在收发消息的过程中&#xff0c;会有很多的问题需要去解决&#xff0c;下面需要学习rabbitMQ的高级特性去解决 死信交换机&#xff1a;这个可以帮助我们实现消息的延迟的…

[office] excel求乘积的公式和方法 #媒体#笔记#经验分享

excel求乘积的公式和方法 本文首先给出两个常规的excel求乘积的链接&#xff0c;然后再例举了一个文字和数字在同一单元格里面的excel求乘积的公式写法。 excel求乘积的方法分为两种&#xff0c;第一种是直接用四则运算的*来求乘积&#xff0c;另外一种就是使用PRODUCT乘积函数…

【GO语言卵细胞级别教程】03.条件与循环语句

注意&#xff1a;以下演示所用的项目&#xff0c;在第一章节已经介绍了&#xff0c;这里不做赘述 目录&#xff1a; 【GO语言卵细胞级别教程】03.条件与循环语句1.条件语句1.1 if语句1.1.1 单层if语句1.1.2 if-else语句1.1.3 if-else-if 语句1.1.4 if 嵌套 1.2 switch 语句1.1…

[论文精读]Community-Aware Transformer for Autism Prediction in fMRI Connectome

论文网址&#xff1a;[2307.10181] Community-Aware Transformer for Autism Prediction in fMRI Connectome (arxiv.org) 论文代码&#xff1a;GitHub - ubc-tea/Com-BrainTF: The official Pytorch implementation of paper "Community-Aware Transformer for Autism P…

Python解决SSL不可用问题

参考&#xff1a;https://blog.csdn.net/weixin_44894162/article/details/126342591 一、问题描述&#xff1a; 报错概述&#xff1a; WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available. ## 警告:pip配…