向量 vector
向量(vector)可以看成是“动态数组”,即可以保存的元素个数是可变的。
与数组相比,使用向量时要注意:向量的大小是可变的。开始时向量为空,随着不断插入元素,向量自动申请空间,容量变大。
vector动态增长基本原理:当插入新元素的时候,如果空间不足,那么vector会重新申请更大的一块内存空间,将原空间数据拷贝到新空间,释放旧空间,再把新元素插入到新申请空间。
一、定义
1、定义vector:
vector<typename> name; //typename可以是任何基本类型,也可以是STL容器
vector<vector<typename> > name; //c++11之前会将>>视为移位操作,所以要加空格> >
2、定义vector数组:
vector<typename> Arrayname[arraySize];
//与vector<vector<typename> >不同的是,一维已经固定长度为arraySize
二、vector的初始化
vector有4种方式初始化,有直接初始化,也要通过拷贝构造函数初始化。
int main(int argc, const char * argv[]) {
//直接构造函数初始化
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
//通过拷贝构造函数初始化
vector<int> v2 = v1;
//使用部分元素来构造
vector<int> v3(v1.begin(), v1.begin() + 1);
vector<int> v4(v1.begin(), v1.end());
//存放三个元素,每个元素都是9
vector<int> v5(3,9);
int arr[] = {2,3,6,7};
vector<int> v5(arr, arr + sizeof(arr)/sizeof(int));
return 0;
}
三、vector的赋值
vector<int> v;
v.assign(5,1);
vector<int> v1;
v1.assign(v.begin(), v.end());
vector<int> v2;
v2 = v1;
四、vector的添加和删除
既然vector是容器,那么就可以向这个容器添加删除元素。
基本用法:
-
front() 返回头部元素的引用,可以当左值
-
back() 返回尾部元素的引用,可以当左值
-
begin() 向量的第一个元素的位置,返回第一个元素迭代器
-
end() 向量的结束位置。注意,返回的迭代器是最后一个元素的后面位置,不是最后一个元素的迭代器
-
push_back()添加元素,只能尾部添加
-
pop_back()移除元素,只能在尾部移除
int main(int argc, const char * argv[]) {
//定义一个vector容器
vector<int> v1;
//插入元素(尾部插入)
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
//迭代器遍历打印
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
//修改头部元素的值(front()返回是引用,可以当左值)
v1.front() = 44;
//输出头部元素
cout<< "头部元素:" << v1.front() << endl;
//修改尾部的值(back()返回是引用,可以当左值)
v1.back() = 99;
//输出尾部元素
cout << "尾部元素" << v1.back() <<endl;
//删除元素(从尾部删除)
v1.pop_back();
//迭代器遍历打印
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
五、vector的push_back强化
push_back是在当前vector的内存末尾拷贝元素进入容器。注意这个地方可能产生浅拷贝,所以容器中的对象要支持拷贝操作。另外,如果vector初始化了个数,而不初始化具体的值,push_back也只会在最后面追加。
int main(int argc, const char * argv[]) {
//初始化10个元素的容器
vector<int> v(10);
//打印容器大小
cout << v.size() << endl;
//push_back添加元素
v.push_back(100);
//打印容器大小
cout << v.size() << endl;
//遍历后的结果是 0 0 0 0 0 0 0 0 0 0 100
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
六、vector的插入元素
vector在尾部添加或者移除元素非常快,在中间操作非常耗时,因为它需要移动元素
vector提供了insert函数,结合迭代器位置插入指定的元素。如果迭代器位置越界,会抛出异常。
insert() 函数有3种用法:
第1种语法:
iterator insert( iterator loc, const TYPE &val );
参数的含义:在指定位置loc前插人值为val的元素,返回指向这个元素的选代器。
第2种语法:
void insert( iterator loc, size_ type num, const TYPE &val );
参数的含义:在指定位置loc前插人num个值为val的元素。
第3种语法:
void insert( iterator loc, input iterator start, input_ iterator end );
参数的含义:在指定位置loc前插人区间 [start, end] 的所有元素。
int main(int argc, const char * argv[]) {
//初始化vector对象
vector<int> v1(10);
//在指定的位置插入元素10的拷贝
v1.insert(v1.begin() + 3, 10);
//在指定的位置插入3个元素11的拷贝
v1.insert(v1.begin(), 3, 11);
//遍历
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
七、vector的删除元素
vector的删除,是根据位置进行删除,如果想要删除某个元素,需要找到当前元素的迭代器位置,再进行删除。
erase(iterator)函数,删除后会返回当前迭代器的下一个位置。
int main(int argc, const char * argv[]) {
//1 创建容器并初始化
vector<int> v1(10);
for (int i = 0; i < v1.size(); i++) {
v1[i] = i;
}
//2 区间删除
//--2.1 删除前3个元素
v1.erase(v1.begin(), v1.begin() + 3);
//--2.2 删除指定位置的元素
v1.erase(v1.begin() +3);
//3 根据元素的值进行删除,删除值为2的元素
v1.push_back(2);
v1.push_back(2);
vector<int>::iterator it = v1.begin();
while (it != v1.end()) {
if (*it == 2) {
it = v1.erase(it); //删除后,迭代器指针会执行下一个位置并返回。
}else{
it++;
}
}
//4 遍历打印
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
八、vector的访问
vector容器可以随机存取元素,也就是说支持[]运算符和at方式存取。
vector的遍历有多种方式,可以根据[]或者迭代器遍历。需要注意的是:
- []方式,如果越界或出现其他错误,不会抛出异常,可能会崩溃,可能数据随机出现
- at方式,如果越界或出现其他错误,会抛出异常,需要捕获异常并处理
- 迭代器提供了逆向遍历,可以通过迭代器来实现逆向遍历,当然上面两种方式也可以
int main(int argc, const char * argv[]) {
//创建vector
vector<int> v1;
//插入元素
for (int i = 0; i < 10; i++) {
v1.push_back(i);
}
//遍历-[]取值
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << " ";
}
cout << endl;
//遍历-at取值
for (int i = 0; i < v1.size(); i++) {
cout << v1.at(i) << " ";
}
cout << endl;
//遍历-迭代器遍历
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
//遍历-迭代器逆向遍历
for (vector<int>::reverse_iterator it = v1.rbegin(); it != v1.rend(); it++) {
cout << *it << " ";
}
cout << endl;
//测试越界
cout << "[]越界:" << v1[20] << endl; //不会抛出异常,可能会崩溃,可能会乱码
cout << "at越界:" << v1.at(20) << endl; //会抛出异常,需要捕获异常
return 0;
}
九、vector总结
-
访问vector信息
访问vector信息的函数有max_size、 size()、 capacity() 和 empty()。
max_size 返回 vector 可以最多容纳元素的数量;
size() 返回 vector 当前元素的数量;
resize() 重新设定向量的大小,即可以保存多少个元素
capacity() 返回 vector 所能容纳的元素数量(在不重新分配内存的情况下);
empty() 判断vector 是否为空,为空时返回TRUE,否则返回FALSE。
clear() 清除向量所有的元素,size变为0 -
存储vector信息
存储vector信息可以使用构造函数、push_back()、insert()、数组运算符、赋值运算符、pop_back()、erase()、begin()、 end()、rbegin()、 rend()、 size、 maxsize 等。
上一篇: 深入了解Angular中的模块和懒加载
下一篇: Java 的 Swing 被什么取代了?