Vector使用总结

STL 2019-03-04 6783 字 2 浏览 点赞

前言

模板类vector是一种动态数组,此篇用于总结它的常用方法。

使用vector

/* 需要导入头文件 */
#include <vector>

/* 通过命名空间 */
std::vector<Type> ...

/* 或者 using编译指令 */
using namespace std;
vector<Type> ...

/* 又或者 using声明 */
using std::vector;
vector<Type> ...

除了int,string,float等C++基本数据类型外,vector也支持存放我们自己设计的数据类型,但此时需要有对应的构造函数才能保证vector正常使用(尤其是拷贝构造函数)。简单示例如下:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Student {
private:
    string name;
    int age;
    long id;
public:
    Student(string name, int age, long id):
            name(name), age(age), id(id)
    {}
    Student(const Student& std) {  /* 拷贝构造函数 */
        name = std.name;
        age = std.age;
        id = std.id;
    }

    friend ostream& operator<< (ostream& os, const Student& std);
};

ostream& operator<< (ostream& os, const Student& std)
{
    return os << "{ " << std.name << " "
              << std.age << " " << std.id << " }";
}

int main()
{
    vector<Student> stdV = {{"zty", 22, 20140010}, {"you", 23, 20140011}};

    vector<Student> stdV2(stdV);

    cout << stdV2[0] << endl;
    cout << stdV2[1] << endl;
    return 0;
}
// 输出:
{ zty 22 20140010 }
{ you 23 20140011 }

容器构造

以下,利用构造函数构造容器。

1.直接声明一个容器,此时容器为空,不能试图访问容器内部,否则段错误(Segmentation fault)。

vector<int> intV;  /* 创建一个容器 */

2.C++11允许声明容器的同时,为其赋初值(C++98不允许):

vector<int> intV = {1, 2, 3, 4};  /* 容器内的第一个元素是1,第二个是2,依次类推 */

3.指定容器大小,并为其填充默认值。此时有两种方法,第一种不写明默认值,默认填充0;第二种写明默认值,则所有位置都被默认值填充:

vector<int> intV(3);  /* 容器大小为3,每个元素的值都为0 */

vector<int> intV(3, 512);  /* 容器大小为3,每个元素的值都为512 */

4.利用数组构造容器:

int array[] = {1, 2, 3, 4};
vector<int> intV(array, array+2);

array是数组array[]的首地址,指向数组的第一个元素;array+2指向数组的第三个元素。容器会拷贝这个区间中的元素作为自己的初始值,需要注意区间是左闭右开。因此对容器intV来说,它的初始值为:1和2。


5.利用容器构造容器:

vector<int> intV1 = {1, 2, 3};
vector<int> intV2(intV1);

此时容器intV2会把容器intV1中的所有元素作为自己的初始化值。简单地说,就是intV1等于intV2


6.利用赋值符号(=)构造容器:

vector<int> intV1 = {1, 2, 3};
vector<int> intV2 = intV1;

intV1等于intV2。


7.也可以有选择地使用已知容器的值:

vector<int> intV1 = {1, 2, 3};
vector<int> intV2(intV1.begin(), intV1.begin()+2);

begin()方法会返回一根指针,指向容器的第一个元素,intV1.begin()+2表示指向容器的第三个元素。构造容器intV2的时候,会使用该区间的元素作为自己的初始值,注意区间左闭右开。也就是说,对容器intV2而言,它有两个初始值:1和2。

对应的还有一个end()方法,返回一根指针,指向容器最后元素的后一位(也就是说,不是容器的最后一个元素,如果想拿到最后一个元素,需要减1)。使用方式:intV1.end()

无论是begin()还是end(),返回的指针类型为:vector<Type>::iterator

容器赋值

以下,为容器赋值。

1.利用赋值符号(=)为容器赋值:

vector<int> intV1 = {1, 2, 3};
vector<int> intV2;
intV2 = intV1;

将intV1赋值给intV2。


2.利用assign()方法为容器赋值。此时根据传参不同,赋值的方式也有会差异,基本类似构造函数的格式:

vector<int> intV;
intV.assign(3, 512);  /* 从容器的第一个元素开始,依次为其赋值512,直到写满三个元素 */
----------------------------------
vector<int> intV1 = {1, 2, 3};
vector<int> intV2;
intV2.assign(intV1.begin(), intV1.end());  /* 将intV1中[begin, end)区间的元素赋给intV2*/
----------------------------------
int array[] = {1, 2, 3};
vector<int> intV2;
intV2.assign(array, array+2);  /* 利用数组元素赋值,[begin, end)区间元素 */

3.互换两个容器中的元素:

vector<int> intV1 = {1, 2, 3};
vector<int> intV2 = {5, 7, 8};

intV1.swap(intV2);

此时容器intV1中的元素与intV2中的元素互换。

读取内容

以下,访问与修改容器元素。

1.利用索引访问容器内元素:

vector<int> intV = {1, 2, 3};

cout << intV[1] << endl;  /* 打印索引为1的元素的值 */
cout << intV.at(1) << endl;  /* 打印索引为1的元素的值 */

intV[0] = 512;  /* 修改容器中索引为0的元素的值,修改为512 */
intV.at(1) = 1024;  /* 修改容器中索引为1的元素的值,修改为1024 */

2.front()方法与back()方法。前者返回容器中第一个元素的引用,后者返回容器中最后一个元素的引用,类型为:vector<Type>::reference

vector<int> intV = {1, 2, 3};

cout << intV.front() << endl;  /* 输出:1 */
cout << intV.back() << endl;  /* 输出:2 */

/* 作为引用,可以被赋值 */
intV.front() = 512;  /* 此时容器第一个元素被修改为512 */

/* 创建容器第一个元素的引用 */
vector<int>::reference r = intV.front();

3.begin()方法与end()方法。前者返回指向容器中第一个元素的指针,后者返回指向容器中最后一个元素的后一位的指针,类型为:vector<Type>::iterator

vector<int> intV = {1, 2, 3};
cout << *intV.begin() <<endl;  /* 输出:1 */
cout << *--intV.end() << endl;  /* 输出:3 */

/* 利用指针修改容器中元素的值 */
*intV.begin() = 512;  /* 此时容器第一个元素被修改为512 */

/* 创建一根指针,指向容器中的第一个元素 */
vector<int>::iterator p = intV.begin();

借此可以实现遍历vector:

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

int main()
{
    vector<int> intV = {1, 2, 3};
    print(intV);

    return 0;
}
// 输出:
1 2 3

4.利用rbegin()方法和rend()方法对容器反向迭代:

void print(vector<int>& intV)
{
    for (vector<int>::reverse_iterator p = intV.rbegin();
         p != intV.rend();
         p ++)
    {
        cout << *p << " ";
    }
    cout << endl;
}

注意指针类型。

说明:
vector<int>::const_iteratorvector<int>::const_reverse_iterator 分别是vector<int>::iteratorvector<int>::reverse_iterator 的只读形式,使用这两种迭代器时,不会修改到容器中的值。不过容器中的insert()erase()方法仅接受这四种类型中的iterator,其它三种不支持。《Effective STL》建议尽量使用iterator取代const_iterator、reverse_iterator和const_reverse_iterator

增删元素

1.push_back()用于追加元素,即,在容器的末尾添加元素:

vector<int> intV = {1, 2, 3};
intV.push_back(512);  /* 容器内容:{1, 2, 3, 512} */

2.insert()用于在容器中插入元素:

vector<int> intV = {1, 2, 3};

/* 指定位置,插入一个元素 */
intV.insert(intV.begin(), 512);  /* {512, 1, 2, 3} */

/* 指定位置,插入n个元素 */
intV.insert(intV.begin()+1, 2, 512);  /* {1, 512, 512, 2, 3} */

/* 指定位置,插入另一个容器中的元素 */
vector<int> intV2 = {10, 11, 12};
intV.insert(intV.begin()+1, intV2.begin(), intV2.end());  
/* {1, 10, 11, 12, 2, 3} */

/* 指定位置,插入一个数组中的元素 */
int array[] = {10, 11, 12};
intV.insert(intV.end()-1, array, array+2);
/* {1, 2, 10, 11, 3} /*

3.erase()用于删除指定位置的元素:

vector<int> intV = {1, 2, 3};

/* 指定位置,删除一个元素 */
intV.erase(intV.begin());  /* {2, 3} */

/* 指定位置,删除一个区间内的元素,遵循“左闭右开” */
intV.erase(intV.begin(), intV.end()-1);  /* {3} */

4.clear()用于清空整个容器:

vector<int> intV = {1, 2, 3};
intV.clear()  /* {} */

其他常用方法

vector<int> intV = {1, 2, 3};

intV.size();  /* 获取容器中的元素个数 */

intV.capacity();  /* 获取容器最多能够存放多少个元素(容量) */

intV.empty();  /* 判断容器是否为空,空返回1,非空0 */

intV.resize(n);  /* 重新设置容器长度,设置为n;
                    如果n大于原容器长度,则多出来的位置填充0;
                    如果n小于原容器长度,则多余的元素被删除(从容器尾开始);
                    */

intV.resize(n, value);  /* 与intV.resize(n)相似,
                           只不过当n大于原容器长度时,多出来的位置填充value;
                           */


本文由 Guan 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论