STL之vector

1 vector初识

1 动态扩展

并不是在原有的空间里面之后续接新的空间,而是找更到的空间,然后将原有的数据拷贝到新的空间,释放原有空间

vector容器的迭代器是支持随机访问的迭代器

2 功能描述和函数原型

复制代码
//默认构造
vector<int> v1;

for (int i = 0; i < 10; i++) {
	v1[i] = i;
}
  1. 主要问题是在 test01() 函数中,你创建了一个空的 vector<int> v1,然后试图用 v1[i] = i 来赋值。这是错误的,因为 v1 是空的,你不能直接用下标访问和赋值。应该使用 push_back() 方法添加元素

    for (int i = 0; i < 10; i++) {
    v1.push_back(i); // 使用push_back添加元素
    }

下面我们来看看vector的构造函数的使用

复制代码
#include<iostream>
#include<vector>
using namespace std;

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

void test01(){
    //默认构造
    vector<int> v1;

    for (int i = 0; i < 10; i++) {
        v1.push_back(i);  // 使用push_back添加元素
    }

    printvt(v1);

    //通过区间方式构造
    vector<int>v2(v1.begin(), v1.end());
    printvt(v2);

    //通过n个element进行构造
    vector<int>v3(10, 100);
    printvt(v3);

    //拷贝构造
    vector<int>v4(v3);
    printvt(v4);
}

int main() {
    test01();  // 调用测试函数
    return 0;
}

2 vector的赋值

三种vector的赋值方式

复制代码
#include<iostream>
#include<vector>
using namespace std;

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

void test01(){
    //默认构造
    vector<int> v1;

    for (int i = 0; i < 10; i++) {
        v1.push_back(i);  // 使用push_back添加元素
    }

    printvt(v1);
    
    //重载符号=,进行赋值
    vector<int>v2;
    v2 = v1;
    printvt(v2);

    //assign方法(区间)
    vector<int>v3;
    v3.assign(v2.begin(), v2.end());
    printvt(v3);
    
    //assign方法(n个元素)
    vector<int>v4;
    v4.assign(10, 100);
    printvt(v4);
}

int main() {
    test01();  // 调用测试函数
    return 0;
}

3 vector的容量和大小

下面是有关于vector这个容量和大小的相关函数

下面是这个代码的演示

复制代码
#include<iostream>
#include<vector>
using namespace std;

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

void test01(){
    //默认构造
    vector<int> v1;

    for (int i = 0; i < 10; i++) {
        v1.push_back(i);  // 使用push_back添加元素
    }

    printvt(v1);
    
    if (v1.empty()) {
        cout << "v1为空" << endl;
    }

    cout << "v1的容器:" << v1.capacity() << endl;
    cout << "v1的大小:" << v1.size() << endl;

    //重新指定大小
    //resize默认是用0进行初始化未赋值的
    //也可以用resize初始化别的数字
    v1.resize(15, 100);
    printvt(v1);
    cout << "v1的容器:" << v1.capacity() << endl;
    cout << "v1的大小:" << v1.size() << endl;

    //这样是会减少这个元素的个数的
    v1.resize(5);
    printvt(v1);
}

int main() {
    test01();  // 调用测试函数
    return 0;
}

警告代码样例

复制代码
v1.resize(15);
printvt(v1);
cout << "v1的容器:" << v1.capacity() << endl;
cout << "v1的大小:" << v1.size() << endl;

//这样是会减少这个元素的个数的
v1.resize(15,100);
printvt(v1);

代码中 v1.resize(15, 100); 没有按预期将新增的元素设为 100,而是保持 0,这是因为 resize() 的第二个参数(即填充值)仅在容器扩容时才会生效

  • **resize(n, val)**只在扩容时填充 val,如果 n <= size(),则不会修改已有元素
  • **assign(n, val)**会直接覆盖整个 vector ,强制所有元素变成 val

4 插入和删除

函数原型

这里的插入和删除都是要迭代器

复制代码
#include<iostream>
#include<vector>
using namespace std;

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

void test01() {
    //默认构造
    vector<int> v1;

    for (int i = 0; i < 10; i++) {
        v1.push_back(i);  // 使用push_back添加元素
    }

    printvt(v1);

    //尾删
    v1.pop_back();
    printvt(v1);

    //插入  提供一个迭代器进行插入
    //头插法1
    v1.insert(v1.begin(), 100);
    printvt(v1);
    
    //头插法2
    v1.insert(v1.begin(), 2, 1000);
    printvt(v1);

    //删除
    //删除1
    v1.erase(v1.begin());
    printvt(v1);

    //删除2
    v1.erase(v1.begin(), v1.end());
    printvt(v1);


}

int main() {
    test01();  // 调用测试函数
    return 0;
}

梳理所用的方法

复制代码
push_back() 元素放入到尾部
pop_back()  弹出尾部元素
erase()  删除元素(需要提供迭代器)
insert() 插入元素(需要提供迭代器)
clear()  清除元素

如何插入到任意位置?

  1. 使用 begin() + index:如果你想在特定索引位置插入元素,可以使用 v1.begin() + index 来获取该位置的迭代器

  2. 使用 find****或其他方式定位迭代器 :如果你要根据某个条件(比如值等于某个数)来插入,可以用 std::find 或其他算法找到迭代器

    // 1. 在索引 2 的位置(第 3 个元素)插入 100
    v1.insert(v1.begin() + 2, 100);
    printvt(v1); // 1 2 100 3 4 5

    // 2. 在值为 3 的元素前面插入 200
    auto it = find(v1.begin(), v1.end(), 3);
    if (it != v1.end()) {
    v1.insert(it, 200);
    }
    printvt(v1); // 1 2 100 200 3 4 5

5 vector数据存储

函数的原型

上面是获取元素的方式

复制代码
#include<iostream>
#include<vector>
using namespace std;

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

void test01() {
    //默认构造
    vector<int> v1;

    for (int i = 0; i < 10; i++) {
        v1.push_back(i);  // 使用push_back添加元素
    }

    printvt(v1);

    //利用[]访问
    for (int i = 0; i < v1.size();i++) {
        cout << v1[i] << " ";
    }
    cout << endl;

    //利用at来进行访问
    for (int i = 0; i < v1.size(); i++) {
        cout << v1.at(i) << " ";
    }
    cout << endl;

    //访问头元素
    cout << "第一个元素为:" << v1.front() << endl;
    //访问尾元素
    cout << "最后一个元素为:" << v1.back() << endl;
}

int main() {
    test01();  // 调用测试函数
    return 0;
}

front()
back()
at()
operator[]

6 vector互换容器

函数原型

我们所需要学习的是怎么使用这个和这个东西的实际用途

复制代码
#include<iostream>
#include<vector>
using namespace std;

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

void test01() {
    vector<int> v1;

    for (int i = 0; i < 10; i++) {
        v1.push_back(i);  // 使用push_back添加元素
    }
    cout << "互换前:" << endl;
    printvt(v1);
 
    vector<int> v2;
    for (int i = 10; i > 0; i--) {
        v2.push_back(i);
    }
    printvt(v2);

    //互换后
    cout << "互换后:" << endl;
    v1.swap(v2);
    printvt(v1);
    printvt(v2);
}
//实际用途:巧妙运用swap收缩内存大小

void test02(){
    vector<int>v;
    for (int i = 0; i < 10000; i++) {
        v.push_back(i);
    }
    cout << "容量大小:" << v.capacity() << endl;
    cout << "容器大小:" << v.size() << endl;

    v.resize(3);
    cout << "容量大小:" << v.capacity() << endl;
    cout << "容器大小:" << v.size() << endl;

    vector<int>(v).swap(v);
    cout << "容量大小:" << v.capacity() << endl;
    cout << "容器大小:" << v.size() << endl;
}

int main() {
    //test01();  // 调用测试函数
    test02();
    return 0;
}

我们这里要重点学习这个巧用swap来缩小内存占用

复制代码
容量大小:12138
容器大小:10000
容量大小:12138
容器大小:3
容量大小:3
容器大小:3

7 预留空间

函数的原型

这个主要的作用是减少重新开辟的时间开销

预留的位置不可以进行初始化,该位置未赋值就无法访问

复制代码
#include<iostream>
#include<vector>
using namespace std;

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

void test01(){
    vector<int>v;
    int num = 0;
    int* p = NULL;
    for (int i = 0; i < 10000; i++) {
        v.push_back(i);
        if (p != &v[0]) {
            p = &v[0];
            num++;
        }
    }
    cout << num << endl;
}

int main() {
    test01();  // 调用测试函数
    return 0;
}

这个一共开辟了24次才截止,但是我们用reserve就一次

复制代码
#include<iostream>
#include<vector>
using namespace std;

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

void test01(){
    vector<int>v;
    v.reserve(100000);
    int num = 0;
    int* p = NULL;
    for (int i = 0; i < 10000; i++) {
        v.push_back(i);
        if (p != &v[0]) {
            p = &v[0];
            num++;
        }
    }
    cout << num << endl;
}

int main() {
    test01();  // 调用测试函数
    return 0;
}

这个一般都是知道元素的大小提前预留空间节省时间的开销

相关推荐
芜湖xin26 分钟前
【题解-洛谷】B4278 [蓝桥杯青少年组国赛 2023] 简单算术题
算法·
理智的灰太狼27 分钟前
题目 3298: 蓝桥杯2024年第十五届决赛真题-兔子集结
算法·职场和发展·蓝桥杯
pumpkin845142 小时前
Rust Mock 工具
开发语言·rust
love530love3 小时前
【笔记】在 MSYS2(MINGW64)中安装 python-maturin 的记录
运维·开发语言·人工智能·windows·笔记·python
阿卡蒂奥3 小时前
C# 结合PaddleOCRSharp搭建Http网络服务
开发语言·http·c#
kingmax542120084 小时前
【洛谷P9303题解】AC- [CCC 2023 J5] CCC Word Hunt
数据结构·c++·算法·广度优先
白熊1884 小时前
【机器学习基础】机器学习入门核心算法:XGBoost 和 LightGBM
人工智能·算法·机器学习
bai_lan_ya5 小时前
数据结构-排序-排序的七种算法(2)
数据结构·算法·排序算法
泉飒5 小时前
lua注意事项
开发语言·笔记·lua
hao_wujing6 小时前
使用逆强化学习对网络攻击者的行为偏好进行建模
开发语言·网络·php