【C++】—— vector使用

简介: 【C++】—— vector使用

前言

1. vector是表示可变大小数组的序列容器。
2. vector就像数组一样,也采用连续的存储空间来存储元素。这样我们就可以采用下标来访问vector的元素;但vector又不是数组,它的大小是动态可变的,会被容器自动处理。
3. 与其他动态序列的容器(比如list、deque等),vector访问元素更加高效,在末尾添加/删除元素更加高效(尾删、尾插);对于不在尾部删除或插入数据操作,效率就低一些。
4. STL库里面vector是一个类模版,使用时需要实例化。(比如: vector<int>)

vector构造函数

STL库里面构造函数参数有空间适配器(allocator),这里先不了解这一方面的内容(后面再详细学习)。

(constructor)构造函数 接口说明
vector (); (重点) 无参构造(默认构造)
vector(size_type n, const value_type& val = value_type()) 构造并初始化成n个val
vector (InputIterator first, InputIterator last); 使用迭代器进行初始化构造
vector (const vector& x); (重点) 拷贝构造
void test1()
{
  vector<int> v1; //无参构造(默认构造)
  vector<int> v2(10, 1); //构造初始化并初始化成10个1
  vector<int> v3(v2.begin(), v2.end()); //使用迭代器区间初始化
  vector<int> v4(v2); //拷贝构造
}

vector迭代器

在string和vector中迭代器并没有广泛使用(可以进行下标访问);但是任何容器中都可以使用迭代器来遍历,通用性比较强。

iterator的使用 接口说明
begin() 和 end() (重点) begin()获取第一个位置的iterator/const_iterator、end()获取最后一个位置的iterator/const_iterator
rbegin() 和 rend() (反向迭代器) rbegin()获取最后一个位置的iterator/const_iterator、rend()获取第一个的iterator/const_iterator

有了迭代器,我们还可以使用范围for这一个语法糖。

这里为了方便观察,就先使用**push_back()**尾插一些数据。

void test2()
{
  vector<int> v1;
  v1.push_back(1);
  v1.push_back(2);
  v1.push_back(3);
  v1.push_back(4);
  v1.push_back(5);
  //正向迭代器
  std::vector<int>::iterator it = v1.begin(); //可以使用auto自动识别类型
  while (it != v1.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;
  //范围for
  for (auto i : v1)
  {
    cout << i << " ";
  }
  cout << endl;
  //反向迭代器
  std::vector<int>::reverse_iterator rit = v1.rbegin(); //可以使用auto自动识别类型
  while (rit != v1.rend())
  {
    cout << *rit << " ";
    rit++;
  }
  cout << endl;
}

vector空间函数

容量空间 接口说明
size() 获取vector中数据个数
capacity() 获取vector中空间容量大小
empty() 判断是否为空
resize() (重点) 改变vector中size并且设置内容
reserve() (重点) 改变vector中的capacity(空间)大小**(扩容)**
void test3()
{
  vector<int> v1(5, 1);
  cout << "size: " << v1.size() << endl;
  cout << "capacity: " << v1.capacity() << endl;
  if (v1.empty())
  {
    cout << "为空" << endl;
  }
  else
  {
    cout << "不为空" << endl;
  }
  //resize,n比size小
  v1.resize(3);
  for (auto i : v1)
  {
    cout << i << " ";
  }
  cout << endl;
  //resize,n比size大(如果比capacity大就扩容)
  v1.resize(10, 2);
  for (auto i : v1)
  {
    cout << i << " ";
  }
  cout << endl;
  
  //reserve扩容
  cout << "扩容前capacity: " << v1.capacity() << endl;
  v1.reserve(20);
  cout << "扩容后capacity: " << v1.capacity() << endl;
}

vector增删查改

这里再多算一个operator [] (下标访问)。

增删查改 接口说明
push_back() (重点) 尾插
pop_back() (重点) 尾删
find() 查找**(这个不在vector容器内,是算法的接口)**
insert() 在pos位置之前插入数据val(也可以插入n个数据)
erase() 删除pos位置的数据(或者删除一段迭代器区间的数据)
swap() 交换两个vector的数据
operator [] (重点) 下标访问
void test4()
{
  vector<int> v;
  //尾插
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  v.push_back(4);
  v.push_back(5);
  v.push_back(6);
  v.push_back(7);
  for (auto i : v)
  {
    cout << i << " ";
  }
  cout << endl;
  //尾删
  v.pop_back();
  v.pop_back();
  for (auto i : v)
  {
    cout << i << " ";
  }
  cout << endl;
  //find查找 
  auto f1 = find(v.begin(), v.end(), 3);//find返回的是迭代器
  cout << *f1 << endl;
  //insert
  v.insert(f1, 2, 66);
  for (auto i : v)
  {
    cout << i << " ";
  }
  cout << endl;
  //erase删除一个数据
  auto f2 = find(v.begin(), v.end(), 1);
  v.erase(f2);
  for (auto i : v)
  {
    cout << i << " ";
  }
  cout << endl;
  //erase删除一段迭代器区间的数据
  auto f3 = find(v.begin(), v.end(), 3);
  auto f4 = find(v.begin(), v.end(), 5);
  v.erase(f3, f4);
  for (auto i : v)
  {
    cout << i << " ";
  }
  cout << endl;
  //swap交换
  vector<int> v1(5, 1);
  v.swap(v1);
  //下标访问
  for (int i = 0; i < v.size(); i++)
  {
    cout << v[i] << " ";
  }
  cout << endl;
}

这里有一个问题,就是迭代器失效问题;在调用reserve、insert或者erase等方法后,之前的迭代器会失效(如果继续使用会出问题)

**解决方法:**在使用过后,记得重新给迭代器赋值。

vector的使用(OJ题)

136. 只出现一次的数字 - 力扣(LeetCode)

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ret=0;
        for(int i=0;i<nums.size();i++)
        {
            ret^=nums[i];
        }
        return ret;
    }
};

118. 杨辉三角 - 力扣(LeetCode)

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>> vv;
        vv.resize(numRows);
        for (int i = 0; i < numRows; i++) {
            // vv[i].resize(i + 1, 0);
            // vv[i][0] = vv[i][i] = 1;
            vv[i].resize(i + 1, 1);
        }
        /*for (int i = 0; i < vv.size(); i++) {
            for (int j = 0; j < vv[i].size(); j++) {
                if (vv[i][j] == 0) {
                    vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
                }
            }
        }*/
        for (int i = 1; i < vv.size(); i++) {
            for (int j = 1; j < vv[i].size() - 1; j++) {
                vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
            }
        }
        return vv;
    }
};

17. 电话号码的字母组合 - 力扣(LeetCode)

这个题有一点难度,我们使用多路递归思路,一次递归来解决。

思路

根据输入的数字,找到对于的字符串,然后多路递归,组成不同的字母组合,最后返回vector类型的对象。

以题目给的示例来分析一下:

这样递归,递归到空时(digits中数的取完后),字母组合完成,尾插到vector类对象v当中。

class Solution {
    string StrA[10]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
public:
    void Func(string digits, int level, string s, vector<string>& v)
    {
        if(level==digits.size())
        {
            if(level)
                v.push_back(s);
            return;
        }
        int num=digits[level]-'0';
        string str=StrA[num];
        for(int i=0;i<str.size();i++)
        {
            Func(digits,level+1,s+str[i],v);
        }     
    }
    vector<string> letterCombinations(string digits) {
        vector<string> ret;
        Func(digits,0,"",ret);
        return ret;
    }
};

vector使用就结束了,使用比较简单,(STL容器的使用比较统一)。

相关文章
|
25天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
17天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
4天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
1天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
253 12
|
19天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
21天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2579 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
3天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
169 2
|
1天前
|
编译器 C#
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
101 65
|
21天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1578 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
4天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
257 2