【STL】:vector | 变长数组的基本使用

214 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情

1、写在前面

大家好,我是翼同学。今天文章的内容是:

  • vector

2、内容

2.1、简介

(1) 概念

vector容器是STL中最常用的容器之一,它实现的是一个动态数组,也就是说,vector会根据元素的插入或删除来动态调整数组内存大小。另一方面,vector擅长在尾部进行插入或删除操作,且时间复杂度为O(1)O(1),而在其他位置进行插入或删除元素则会耗费一点时间,其时间复杂度为 O(n)O(n)

(2) 导入

vector容器以类模板vector<T>的形式定义在<vector>头文件中,并位于std命名空间中。

当我们需要使用到vector容器时需导入,即代码应包含以下内容:

#include <vector>
using namespace std;

2.2、创建容器

(1) 创建空容器

举个例子:

vector<double> vals;

上述代码创建了一个存储double类型元素的动态数组values,并且该数组是空的,没有数据元素的(当然也就没有分配内存空间)。

当添加第一个元素后,该数组就会自动分配内存。

(2) 创建容器并指定初始值

举个例子:

vector<int> vals {10, 20, 30, 40, 50};

在上述代码中,创建了一个含有五个元素的vector容器,并进行了初始化赋值。

(3) 创建容器并指定元素个数

vector<double> vals(5);

在上述代码中,vals容器在创建时就有5个元素,并且默认初始值为0。


如果想改变默认初始化值,则可以这样:

vector<double> vals(5, 8);

在上述代码中,vals容器在创建时就有5个元素,并且每个元素的初始值都为8。

(4) 拷贝创建

通过存储元素类型相同的其它vector容器可以创建新的vector容器。

举个例子:

vector<double> val1(5, 1);
vector<double> val2(val2);

像这样,val2容器和val1一样,具有五个元素并且每个元素都初始化为1。

2.3、访问vector中的元素

(1) 通过下标访问

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

int main(){
    vector<int> v(5, 1);
	cout << v[0];
    return 0;
}

输出结果:

1

(1) 通过迭代器访问

前面讲过,我们可以将迭代器iterator理解为指针,定义方法如下:

vector<类型名>::iterator 变量名;

这里先介绍三个函数:

v.push_back(val);   // 向数组v的尾部添加一个数据元素 val
v.begin();          // 返回数组v的首元素地址
v.size();           // 返回数组v的长度(即元素个数)

那么来举个例子:

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

int main() {
    // 定义一个动态数组 vi
    vector<int> vi;

    // 往数组 vi 的尾部添加 5 个数据元素
    for (int i = 0; i < 5; i++) {
        vi.push_back(i);
    }

    // 定义一个迭代器 it
    vector<int>::iterator it = vi.begin();

    // 通过迭代器访问数组元素
    for (int i = 0; i < vi.size(); i++)
    {
       cout << it[i] <<" ";
    }

    return 0;
}

运行结果:

0 1 2 3 4

另外需要注意,it[i]也能写成*(it+i),这两个写法等价。也就是说,上述的for循环输出数组元素时可以这样:

for (int i = 0; i < v.size(); i++) {
    cout << *(it+i) << " " ;
}

2.4、常用函数

push_back( )

  • 该函数用于在容器的末尾添加一个指定的元素。

举个例子:

#include <iostream>
#include <vector>
using namespace std;
// v.push_back(item)用于在数组的末尾添加数据元素 item
int main() {
    vector<int> v;
    for (int i = 0; i < 5; i++) {
        v.push_back(i);
        cout << v[i] << " ";
    }
    return 0;
}

运行结果:

0 1 2 3 4

pop_back( )

  • 该函数用于弹出数组的最后一个元素。

举个例子:

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

int main(){
    vector<int> v;
    for (int i = 0; i < 5; i++) {
        v.push_back(i);
    }

    cout << "弹出前,数组:";
    for (int i = 0; i < v.size(); i++) {
        cout<<v[i]<<" ";
    }
    cout<<endl;

    // 弹出一个数据元素
    v.pop_back();

    cout<<"弹出后,数组:";
    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << " ";
    }
    
    return 0;
}

运行结果:

弹出前,数组:0 1 2 3 4
弹出后,数组:0 1 2 3

size( )

该函数用于返回容器的长度,即所含元素的个数。

举个例子:

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

int main(){
    vector<int> v;
    for (int i = 0; i < 10; i++) {
        v.push_back(i);
    }
    cout << v.size() << endl;
    return 0;
}

运行结果:

10

clear( )

该函数用于清空容器中的所有元素。

举个例子:

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

int main(){
	
    vector<int> v;
    
    for (int i = 0; i < 5; i++) {
        v.push_back(i);
    }
    
    cout << "清空前,数组长度:" << v.size() <<endl;
    
    v.clear();
    
    cout << "清空后,数组长度:" << v.size() <<endl;
    
    return 0;
}

运行结果:

清空前,数组长度:5
清空后,数组长度:0

insert( )

该函数用于在指定的位置插入一个元素。

举个例子:

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

int main() { 
    vector<int> v(4);
    
    cout << "插入前:" ; 
    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << " ";
    }
    
    v.insert(v.begin()+2, 8);
    
    cout << "\n插入后:";
    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << " ";
    }
    
    return 0;
}

运行结果:

插入前:0 0 0 0
插入后:0 0 8 0 0

erase( )

对于删除操作,我们除了可以使用清空容器元素的函数clear()之外,还可以使用erase()函数。并且该函数可以用两种使用方法。

  • 一是删除指定位置的元素。

举个例子:

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

int main(){
    vector<int> v;
	for (int i = 0; i < 5; i++){
        v.push_back(i);
    }
    
    cout << "删除前:"; 
    for (int i = 0; i < v.size(); i++) {
        cout<<v[i]<<" ";
    }

    v.erase(v.begin()+2);
    
    cout << "\n删除后:";
    for (int i = 0; i < v.size(); i++) {
        cout<<v[i]<<" ";
    }
    
    return 0;
}

运行结果:

删除前:0 1 2 3 4
删除后:0 1 3 4

  • 另一种删除操作就是删除指定区间内的元素
  • 函数为:erase(posBegin, posEnd);
  • 注意,删除区间是左闭右开的,即[posBegin,posEnd)[posBegin,posEnd)

举个例子:

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

int main() {
	
    vector<int> v;
    
    cout << "删除前,数组元素为:"; 
    for (int i = 0; i < 5; i++) {
        v.push_back(i);
        cout << v[i] << " ";
    }

    // 删除数组 v 中,区间在 [1, 4) 的元素
    v.erase(v.begin()+1, v.begin()+4);
    
    cout << "\n删除后,数组元素为:"; 
    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << " ";
    }
    return 0;
}

运行结果为:

删除前,数组元素为:0 1 2 3 4
删除后,数组元素为:0 4

2.5、小结

最后小结一下vector容器的常用成员函数。

  • push_back():在序列的尾部添加一个元素。
  • pop_back():移出序列尾部的元素。
  • begin():返回指向容器中首元素的迭代器。
  • end():返回指向容器中末元素所在位置的后一个位置的迭代器。
  • rbegin():返回指向最后一个元素的迭代器。
  • rend():返回指向第一个元素所在位置前一个位置的迭代器。
  • cbegin():和begin()类似,只不过cbegin()不能用于修改元素。
  • cend():和end()类似,只不过在其基础上,增加了 const 属性,不能用于修改元素。
  • crbegin() 和 rbegin() 功能相同,只不过cend()不能用于修改元素。
  • crend()rend()功能相同,只不过crend()不能用于修改元素。
  • size():返回容器中实际元素的个数。
  • resize():改变容器实际元素的个数。
  • capacity():返回容器当前的容量。
  • empty():判断容器是否为空,若容器无元素,则返回true,反之返回false
  • reserve():增加容器的容量。
  • operator[ ] 重载了[ ]运算符,此时可通过下标访问甚至修改容器中的元素。
  • at():使用经过边界检查的索引访问元素。
  • front():返回第一个元素的引用。
  • back():返回最后一个元素的引用。
  • data():返回指向容器中第一个元素的指针。
  • assign():用新元素替换原有内容。
  • insert():在指定的位置插入一个或多个元素。
  • erase():删除一个元素或一段元素。
  • clear():清空所有元素,并将容器大小变为0
  • swap():交换两个容器中的所有元素。
  • emplace():在指定的位置直接生成一个元素。
  • emplace_back():在序列尾部生成一个元素。
  • shrink _to_fit():将内存减少到等于当前元素实际所使用的大小。

3、写在最后

好了,文章的内容就到这里,感谢观看。