前言
模板类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_iterator
与 vector<int>::const_reverse_iterator
分别是vector<int>::iterator
与vector<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;
*/
还不快抢沙发