当前位置: 首页 > news >正文

C++学习笔记(二十五)——vector

一、std::vector

(1)vector与其适用场景

作用:
std::vector 是 C++ 标准模板库(STL)中的动态数组,它的大小可以动态增长或缩小,并且提供了自动内存管理和丰富的操作函数

特点:

  • 自动管理内存(不需要手动 new/delete)。
  • 动态扩展(不像普通数组需要固定大小)。
  • 支持随机访问O(1) 复杂度)。
  • 丰富的内置函数(插入、删除、查找、排序等)。

适用场景:

  • 适用于需要动态增长的数组
  • 适用于需要快速访问(O(1))的情况
  • 适用于需要内存自动管理的情况

包含头文件

#include <vector>

(2)vector vs 数组

特性vector数组 (int arr[])
大小动态调整固定大小
内存管理自动手动管理
元素访问O(1)O(1)
安全性at() 提供边界检查访问越界可能崩溃
功能具备 insert, erase, sort 等功能需要手写

二、std::vector 的创建

函数作用
vector<T> vec;默认构造一个空vector
vector<T> vec(n);创建一个大小为nvector,默认初始化元素
vector<T> vec(n, val);创建一个大小为n,值为valvector
vector<T> vec = {val1, val2, ...};使用列表初始化
vector<T> vec(other_vec);拷贝构造
vector<T> vec(other_vec.begin(), other_vec.end());迭代器范围构造

(1) 定义 vector

示例:

#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>

void printVector(const vector<int> v)
{
    for (int x : v)
    {
        cout << x << " ";
    }
    cout << endl;
}

int main() {
    vector<int> v1;              // 创建空 vector
    vector<int> v2(5);           // 创建包含 5 个元素的 vector,默认值为 0
    vector<int> v3(5, 100);      // 创建 5 个 100
    vector<int> v4 = {1, 2, 3};  // 直接初始化
    vector<int> v5(v4);          // 复制另一个 vector

    printVector(v1);
    printVector(v2);
    printVector(v3);
    printVector(v4);
    printVector(v5);

    system("pause");
    return 0;
}

(2) 向 vector 添加元素

示例:

#include <iostream>
using namespace std;
#include <vector>

int main() {
    vector<int> v;
    v.push_back(10);   // 添加元素
    v.push_back(20);
    v.emplace_back(30); // 效率更高

    for (int x : v)
    {
        cout << x << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

注意:

  • push_back:先构造一个临时对象,然后拷贝/移动到容器中。
  • emplace_back直接在容器的内存空间中构造对象,避免临时对象的创建和拷贝/移动,提高效率

(3) 访问 vector 元素

函数作用
vec[i]索引访问,无越界检查
vec.at(i)索引访问,带越界检查(越界抛异常
vec.front()返回第一个元素
vec.back()返回最后一个元素
vec.data()返回指向底层数组的指针

示例:

#include <iostream>
using namespace std;
#include <vector>

int main() {
    vector<int> v;
    v.push_back(10);   // 添加元素
    v.push_back(20);
    v.emplace_back(30); // 效率更高

    cout << v[0] << endl;       // 直接访问
    cout << v.at(1) << endl;    // 安全访问,带边界检查
    cout << v.front() << endl;  // 获取第一个元素
    cout << v.back() << endl;   // 获取最后一个元素

    system("pause");
    return 0;
}

三、遍历 vector

(1) 使用 for 循环

示例:

#include <iostream>
using namespace std;
#include <vector>

int main() {
    vector<int> v = {10, 20, 30, 40, 50};  // 直接初始化

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

    system("pause");
    return 0;
}

(2) 使用范围 for

作用:

  • C++11 引入了范围基 for 循环(range-based for loop),用于简洁、直观地遍历容器(如 vector、list、map 等)。

语法:

for (元素类型 变量 : 容器) {
    // 操作变量
}

遍历方式:

  • 值遍历for (auto x : container) —— 拷贝元素(适用于基本类型)。
  • 引用遍历for (auto& x : container) —— 避免拷贝,提高效率。
  • 常引用遍历for (const auto& x : container) —— 保护数据,防止修改。

示例:

#include <iostream>
using namespace std;
#include <vector>

int main() {
    vector<int> v = {10, 20, 30, 40, 50};  // 直接初始化

    for (int x : v) 
    {
        cout << x << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

(3) 使用迭代器

函数作用
vec.begin()返回指向首元素的迭代器
vec.end()返回指向尾后元素的迭代器
vec.rbegin()返回指向末元素的反向迭代器
vec.rend()返回指向首元素前的反向迭代器

示例:

#include <iostream>
using namespace std;
#include <vector>

int main() {
    vector<int> v = {10, 20, 30, 40, 50};  // 直接初始化

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

    system("pause");
    return 0;
}

四、 std::vector 的常用操作

(1) 插入、删除

函数作用
vec.push_back(val)尾部添加元素
vec.emplace_back(args...)尾部原地构造元素(比push_back更高效)
vec.insert(pos, val)pos位置插入val
vec.insert(pos, n, val)pos位置插入nval
vec.insert(pos, first, last)pos位置插入迭代器范围的元素
vec.erase(pos)删除pos位置的元素
vec.erase(first, last)删除[first, last)范围内的元素
vec.pop_back()删除尾部元素
vec.clear()清空所有元素

示例:

#include <iostream>
using namespace std;
#include <vector>

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

int main() {
    vector<int> v = {1, 2, 3, 4};
    printVector(v);

    // 插入元素
    v.insert(v.begin() + 2, 100); // 在索引 2 位置插入 100, (1,2,100,3,4)
    printVector(v);

    // 删除元素
    v.erase(v.begin());           // 删除第一个元素 (2,100,3,4)
    printVector(v);
    v.erase(v.begin() + 2);       // 删除索引 2 处的元素 (2,100,4)
    printVector(v);

    // 清空 vector
    v.clear();
    printVector(v);

    system("pause");
    return 0;
}

(2) vector 的大小

函数作用
vec.size()返回当前元素数量
vec.empty()判断是否为空
vec.capacity()返回当前分配的存储容量
vec.shrink_to_fit()减少capacity使其等于size
vec.reserve(n)预分配至少n个元素的空间
vec.resize(n)调整大小为n,新元素默认构造
vec.resize(n, val)调整大小为n,新元素初始化为val

示例:

#include <iostream>
using namespace std;
#include <vector>

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

int main() {
    vector<int> v = {1, 2, 3, 4};
    cout << v.size() << endl;     // 获取元素个数
    cout << v.capacity() << endl; // 获取当前容量
    cout << v.empty() << endl;    // 是否为空

    v.resize(10);      // 重新设定大小,默认填充 0
    printVector(v);

    v = {1, 2, 3, 4};
    v.resize(10, 5);   // 填充 5
    printVector(v);

    system("pause");
    return 0;
}

(3)vector 的排序

函数作用
vec.size()返回当前元素数量
sort(vec.begin(), vec.end())排序
reverse(vec.begin(), vec.end())逆序
find(vec.begin(), vec.end(), val)查找元素
binary_search(vec.begin(), vec.end(), val)二分查找(需排序)

示例:

#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>

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

int main() {
    vector<int> v = { 3, 1, 4, 5, 2 };
    printVector(v);

    sort(v.begin(), v.end());  // 升序排序
    printVector(v);
    reverse(v.begin(), v.end());  // 逆序
    printVector(v);

    system("pause");
    return 0;
}

(4) 交换 vector

示例:

#include <iostream>
using namespace std;
#include <vector>

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

int main() {
    vector<int> a = {1, 2, 3};
    vector<int> b = {4, 5, 6};
    cout << "交换前: " << endl;
    printVector(a);
    printVector(b);

    a.swap(b);  // 交换 a 和 b 的内容
    cout << "交换后: " << endl;
    printVector(a);
    printVector(b);

    system("pause");
    return 0;
}

注意:
a.swap(b); 交换 a 和 b 的所有元素,避免数据拷贝,提高性能。

相关文章:

  • OpenCV第2课 OpenCV的组成结构与图片/视频的加载及展示
  • MapReduce1中资源预先划分为固定数量的map slot和reduce slot,具体是怎么划分的?
  • 深度强化学习(Deep Reinforcement Learning, DRL)
  • java 批量下载doc\excle\pdf
  • leetcode-12.整数转罗马数字
  • git 标签学习笔记
  • Android Monkey测试完全指南:从入门到实战
  • allure结合pytest生成测试报告
  • chrome插件开发之API解析-chrome.tabs.query
  • 【智能搜索引擎技术】第四章搜索引擎索引构建(水课复习自用)
  • Qt在ARM中,如何使用drmModeObjectSetProperty 设置 Plane 的 zpos 值
  • 识别并脱敏上传到deepseek/chatgpt的Word文件中的敏感信息
  • 视频知识库初步设想
  • 游戏摇杆开发:利用 Windows API 实现摇杆输入捕获
  • 【模拟面试】计算机考研复试集训(第十二天)
  • 开源在线客服系统源码-前端源码加载逻辑
  • VUE2导出el-table数据为excel并且按字段分多个sheet
  • 【算法】区间合并
  • 白盒测试用例的设计(图文讲解)
  • 22、web前端开发之html5(三)
  • 零食连锁鸣鸣很忙递表港交所:去年营收393亿元,门店超1.4万家,净利润率2.1%
  • 广东省副省长刘红兵跨省任湖南省委常委、宣传部部长
  • 澎湃读报丨解放日报9个版聚焦:上海,加快建成具有全球影响力的科技创新高地
  • 新开发银行如何开启第二个“金色十年”?
  • 南京航空航天大学启动扁平化改革:管理岗规模控制在20%,不再统一设科级机构
  • 辽宁辽阳火灾事故饭店经营者已被控制,善后处置全面展开