[C++] 一文带你精通vector容器

简介: [C++] 一文带你精通vector容器

基本概念

C++ 中的 vector 是一种顺序容器,是一个封装了动态大小数组的顺序容器,可以存放任意类型的数据。vector 可以随着元素的加入自动扩充其大小,并且支持在中间插入或删除元素。

vector 的声明方式为:

vector<元素类型> 数组名;

例如,声明一个储存整数的 vector 变量可以这样写:

vector<int> myVector;

vector 作为一个重要的 C++ STL 容器,在企业开发中有很多应用场景,可以方便地管理和处理大量数据、实现高效算法和数据结构、实现容器适配器和自定义数据结构等。

例如,在企业开发中,经常需要使用一些高效的算法和数据结构来处理特定问题,如排序、图形处理等。vector 提供了快速随机访问元素的优势,可以方便地实现这些算法和数据结构,提高程序效率和质量。

在处理大量数据,如读取文件、处理数据库查询结果集时, vector 可以根据需要自动扩容和释放内存,因此可以灵活地管理内存空间,保证程序运行效率,并且方便对数据进行快速访问。

因此,在学习C++时,熟悉和掌握vector是非常重要的。

主要特点

vector 的主要特点包括:

1. 动态分配内存

vector 内部使用动态分配内存的方式存储元素,可以根据需要自动调整内存空间大小,不需要事先指定容器大小。

2. 随机访问元素

vector 支持通过下标运算符 []at() 函数快速访问元素,复杂度为 O(1),可以用作普通数组一样的数据结构。

3. 在尾部插入和删除元素效率高

由于 vector 内部使用连续的内存存储元素,因此在序列的尾部插入或删除元素效率非常高,复杂度为 O(1)。

4.插入和删除元素效率低

由于 vector 内部采用的是连续的内存存储方式,当需要在序列中间位置插入或删除元素时,需要将该位置之后的元素全部移动,导致效率较低,复杂度为 O(n)。

5. 可以存储任意类型的元素

由于 vector 是一个模板类,因此可以存储任意类型的元素,在实际应用中非常灵活。

常用操作

vector 容器支持添加、访问、删除、插入、替换和清空元素等基本操作:

1.创建 vector 容器:可以通过 vector 类模板来创建一个新的 vector 容器,语法为 std::vector<T> v;,其中 T 表示存储在 vector 中的元素类型。

std::vector<int> v;

2.添加元素:使用 push_back() 函数可以向 vector 容器的末尾添加一个新元素,语法为 v.push_back(elem);,其中 elem 表示要添加的元素。

//向 vector 容器中添加元素 5
v.push_back(5);

3.访问元素:vector 容器支持通过下标运算符 [] 和 at() 函数访问元素,语法分别为 v[i]v.at(i),其中 i 表示要访问的元素下标。

//访问 vector 容器中第三个元素
int elem = v[2];

4.删除元素:使用 erase() 函数可以删除 vector 容器中指定范围内的元素,语法为 v.erase(start, end);,其中 start 和 end 分别表示要删除元素的起始位置和终止位置。

//删除 vector 容器中第二个到第四个元素
v.erase(v.begin() + 1, v.begin() + 4);

5.获取容器大小:使用 size() 函数可以获取 vector 容器中元素的数量,语法为 v.size();

//获取 vector 容器中元素的数量
int size = v.size();

6.判断容器是否为空:使用 empty() 函数可以判断 vector 容器是否为空,语法为 v.empty();

bool isEmpty = v.empty();

7.清空容器:使用 clear() 函数可以清空 vector 容器中的所有元素,语法为 v.clear();

v.clear();

8.插入元素:使用 insert() 函数可以在 vector 容器中指定位置插入一个新元素,语法为 v.insert(pos, elem);,其中 pos 表示插入位置的迭代器,elem 表示要插入的元素。

//在 vector 容器中第二个位置插入元素 3
v.insert(v.begin() + 1, 3);

9.替换元素:使用赋值运算符 = 和 assign() 函数可以替换 vector 容器中指定位置的元素,语法分别为 v[i] = elem;v.assign(pos, end, elem);,其中 i 表示要替换元素的下标,pos 和 end 表示要替换元素的范围,elem 表示替换的新元素。

//将 vector 容器中第四个元素替换为 7
v[3] = 7;

应用实例

给定一个题目:

请实现一个MyQueue类,实现出队,入队,求队列长度:

实现入队函数 void push(int x);

实现出队函数 int pop();

实现求队列长度函数 int size();

输入格式:

每个输入包含1个测试用例。每个测试用例第一行给出一个正整数 n (n <= 10^6) ,接下去n行每行一个数字,表示一种操作:

1 x : 表示从队尾插入x,0<=x<=2^31-1。

2 : 表示队首元素出队。

3 : 表示求队列长度。

输出格式:

对于操作2,若队列为空,则输出 “Invalid”,否则请输出队首元素。 对于操作3,请输出队列长度。

每个输出项最后换行。


可以使用vector容器实现题目求解:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> obj; //定义一个 vector 对象 obj,用来存储队列元素
int duilie=0,ren=0; //定义两个变量,表示队列的长度和队首元素位置
class MyQueue { //定义 MyQueue 类
    private:
    public:
    void push(int x) { //定义 push 函数,将元素 x 加入队列
        obj.push_back(x); //在 vector 尾部添加元素
        duilie++; //队列元素个数加 1
    }
    int pop() { //定义 pop 函数,弹出队首元素并返回该元素值
        if(duilie==0) //如果队列为空,弹出无效,输出 "Invalid"
            cout<<"Invalid"<<endl;
        if(duilie!=0) //否则,从队列中删除队首元素,并输出该元素值
        {
            cout<<obj[0]<<endl;
            vector<int>::iterator s = obj.begin(); //定义迭代器 s,将其指向 vector 的起始位置
            obj.erase(s); //在 vector 中删除起始位置的元素
            duilie--; //队列元素个数减 1
        }
    }
    int size() { //定义 size 函数,返回队列元素个数(即队列长度)
        int i;
        for(i=0;i<obj.size();i++)
        {
            ;
        }
        cout<<i<<endl; //输出元素个数 i
    }
};
int main(int argc, char *argv[]) {
    unsigned long long int i,j,k;
    cin>>i; //输入操作次数
    MyQueue a; //创建 MyQueue 对象 a
    for(j=0;j<i;j++) //进行 i 次操作
    {
        cin>>k; //输入操作类型
        switch(k)
        {
            case 1: 
//如果操作类型为 1,再输入要加入队列的元素值 x,
//并调用 push 函数将其加入队列
                int x;
                cin>>x;
                a.push(x);
                break;
            case 2: //如果操作类型为 2,调用 pop 函数弹出队首元素
                a.pop();
                break;
            case 3: //如果操作类型为 3,调用 size 函数返回队列长度
                a.size();
        }
    }
}

相较优势

若不适用vector容器,也可使用静态数组解题:

#include<iostream>
using namespace std;
const int MAXSIZE = 100010; //定义静态数组最大长度
class MyQueue { //定义 MyQueue 类
    private:
        int data[MAXSIZE]; //定义一个静态数组 data,用来存储队列元素
        int duilie=0,ren=0; //定义两个变量,表示队列的长度和队首元素位置
    public:
        void push(int x) { //定义 push 函数,将元素 x 加入队列
            data[duilie++] = x; //在数组尾部添加元素,并将队列元素个数加 1
        }
        int pop() { //定义 pop 函数,弹出队首元素并返回该元素值
            if(duilie==ren) //如果队列为空,弹出无效,输出 "Invalid"
                cout<<"Invalid"<<endl;
            else { //否则,弹出队首元素,输出该元素值,并将队列元素个数减 1
                cout<<data[ren++]<<endl;
            }
        }
        int size() { //定义 size 函数,返回队列元素个数(即队列长度)
            cout<<duilie-ren<<endl; //输出队列元素个数
        }
};
int main(int argc, char *argv[]) {
    int i,j,k;
    cin>>i; //输入操作次数
    MyQueue a; //创建 MyQueue 对象 a
    for(j=0;j<i;j++) //进行 i 次操作
    {
        cin>>k; //输入操作类型
        switch(k)
        {
            case 1: //如果操作类型为 1,再输入要加入队列的元素值 x,并调用 push 函数将其加入队列
                int x;
                cin>>x;
                a.push(x);
                break;
            case 2: //如果操作类型为 2,调用 pop 函数弹出队首元素
                a.pop();
                break;
            case 3: //如果操作类型为 3,调用 size 函数返回队列长度
                a.size();
        }
    }
}

对于上述代码中使用的静态数组和 vector 容器,两者在实现队列数据结构时的具体实现方式是不同的。

在使用静态数组时,需要在定义数组时指定其最大长度,并在操作队列过程中手动维护队列的长度和队首元素位置,如下所示:

class MyQueue {
private:
    int data[MAXSIZE];
    int duilie=0,ren=0;
public:
    void push(int x) {
        data[duilie++] = x;
    }
    int pop() {
        if(duilie==ren)
            cout<<"Invalid"<<endl;
        else {
            cout<<data[ren++]<<endl;
        }
    }
    int size() {
        cout<<duilie-ren<<endl;
    }
};

在使用 vector 容器时,可以直接使用 vector 的成员函数对元素进行插入和删除,同时 vector 会在需要时自动扩容,并且 vector 容器的 size() 成员函数可以返回容器中元素的个数,如下所示:

class MyQueue {
private:
    vector<int> obj;
public:
    void push(int x) {
        obj.push_back(x);
    }
    int pop() {
        if(obj.empty())
            cout<<"Invalid"<<endl;
        else {
            cout<<obj.front()<<endl;
            obj.erase(obj.begin());
        }
    }
    int size() {
        cout<<obj.size()<<endl;
    }
};

因此,相比于静态数组,vector 容器在实现队列数据结构时的操作更加便捷,而且不需要手动维护队列的长度和队首元素位置,使用起来更加便捷。

总结

本文介绍了vector容器的特点语法操作应用实例等,vector容器在数据的处理中不可或缺,读者可躬身实践将其掌握。

我是秋说,我们下次见。

目录
相关文章
|
2月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
54 2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
2月前
|
存储 C++ 索引
【C++打怪之路Lv9】-- vector
【C++打怪之路Lv9】-- vector
23 1
|
2月前
|
安全 测试技术 C++
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化2
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化
65 6
|
2月前
|
编译器 C++
【C++】—— vector模拟实现
【C++】—— vector模拟实现
|
2月前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
55 5
|
2月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
59 2
|
2月前
|
算法 C++ 容器
C++之打造my vector篇(下)
C++之打造my vector篇(下)
30 0
|
2月前
|
存储 编译器 C++
C++之打造my vector篇(上)
C++之打造my vector篇(上)
29 0
|
2月前
|
算法 C++ 容器
【C++】—— vector使用
【C++】—— vector使用
|
2月前
|
存储 缓存 C++
C++番外篇——list与vector的比较
C++番外篇——list与vector的比较
23 0