赞
踩
vector 翻译为“向量”,也可称为“变长数组”,即“长度根据需要而自动改变的数组”。
vector 动态增长的原理:当插入新元素的时候,如果空间不足,那么 vector 会重新申请更大的一块内存空间,将原空间数据拷贝到新空间,释放旧空间,再把新元素插入到新申请空间。
头文件 include <vector>
#include <iostream> #include <vector> #include <string> using namespace std; int main() { vector<int> v1; // int类型的空vector vector<string> v2; // string类型的空vector vector<int> v3(20, -10); // 创建20个int类型的元素,每个元素的值为-10 vector<string> v4(15, "hello"); // 创建15个string类型的元素,每个元素的值为hello vector<int> v5(20); // 创建20个int类型的元素,每个元素值默认为0 vector<string> v6(15); // 创建15个string类型的元素,每个元素值默认为空串 vector<int> v7(v3); // 通过拷贝构造函数初始化 vector<string> v8 = v4; // 通过拷贝构造函数初始化 vector<int> v9(v3.begin(), v3.end()); return 0; }
在 C++11 标准中,可以用列表初始化方法给值,即用 {}
括起来。
#include <iostream> #include <vector> #include <string> using namespace std; int main() { vector<int> v1(10); // 创建10个int类型的元素,每个元素值为0 vector<int> v2{10}; // 创建1个int类型的元素,该元素的值为10 vector<int> v3(10, 1); // 创建10个int类型的元素,每个元素值为1 vector<int> v4{10, 1}; // 创建2个int类型的元素,元素值分别为10和1 vector<string> v5 = {"aaa", "bbb", "ccc"}; vector<string> v6(10); // 创建10个string类型的元素,每个元素值默认为空串 vector<string> v7{10}; // 创建10个string类型的元素,每个元素值默认为空串 vector<string> v8(10, "hello"); // 创建10个string类型的元素,每个元素值默认为hello vector<string> v9{10, "hello"}; // 创建10个string类型的元素,每个元素值默认为hello return 0; }
#include <iostream> #include <vector> using namespace std; int main() { vector<int> v1; v1.assign(5, 1); // 将5个1赋值给v1 vector<int> v2; v2.assign(v1.begin(), v1.end()); // 将v1的[begin,end)赋值给v2 vector<int> v3; v3 = v1; return 0; }
size()
用来获得 vector 中元素的个数,时间复杂度为
O
(
1
)
O(1)
O(1)。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v{10, 20, 30, -10, -20, -30};
cout << v.size() << endl; // 6
return 0;
}
push_back(x)
就是在 vector 后面添加一个元素 x
,时间复杂度为
O
(
1
)
O(1)
O(1)。
pop_back()
用以删除 vector 的最后一个元素,时间复杂度为
O
(
1
)
O(1)
O(1)。
vector 在尾部添加或删除元素非常快。在中间操作非常耗时,因为它需要移动元素。
#include <iostream> #include <vector> using namespace std; int main() { vector<int> v; v.push_back(11); v.push_back(22); v.push_back(33); v.pop_back(); cout << v.size() << endl; // 2 return 0; }
如果两个 vector 的元素数量相等并且对应位置的元素值也相等,那么这两个 vector 就相等,否则不相等。
#include <iostream> #include <vector> using namespace std; int main() { vector<int> v1 = {100, 200, 300, -10, -20, -30}; vector<int> v2 = {100, 200, 300, -1, -2, -3}; if (v1 == v2) { cout << "v1 == v2" << endl; } else { cout << "v1 != v2" << endl; } return 0; }
vector 容器可以随机存取元素。
和访问普通数组一样,对于 vector 容器来说,直接访问 v[index]
即可。当然,这里的下标 index
是从 0
到 v.size()-1
,访问这个范围外的元素可能会运行出错。
[]
方式,如果越界或出现其他错误,不会抛出异常,可能崩溃,可能数据随机出现。
#include <iostream> #include <vector> using namespace std; int main() { vector<int> v{10, 20, 30, -10, -20, -30}; for (int i = 0; i < v.size(); i++) { cout << v[i] << " "; } cout << endl; return 0; }
at()
方式,如果越界或出现其他错误,会抛出异常,需要捕获异常并处理。
#include <iostream> #include <vector> using namespace std; int main() { vector<int> v{10, 20, 30, -10, -20, -30}; for (int i = 0; i < v.size(); i++) { cout << v.at(i) << " "; } cout << endl; return 0; }
#include <iostream> #include <vector> using namespace std; int main() { vector<int> v = {100, 200, 300, -10, -20, -30}; for (auto &x : v) { x *= 2; } for (auto &x : v) { cout << x << endl; } return 0; }
迭代器可以理解为一种类似于指针
的东西,通过迭代器我们可以读容器中的元素值,还可以修改某个迭代器所指向的元素值。
迭代器的定义如下,iter
就是一个 vector<typename>::iterator
类型的变量,其中 typename
就是定义 vector 时所填写的类型。
vector<typename>::iterator iter;
v[i]
和 *(v.begin()+i)
是等价的。需要注意的是,在常用 STL 容器中,只有在 vector 和 string 中,才允许使用 v.begin()+i
这种迭代器加上整数的写法。
#include <iostream> #include <vector> using namespace std; int main() { vector<int> v{10, 20, 30, -10, -20, -30}; vector<int>::iterator iter = v.begin(); for (int i = 0; i < v.size(); i++) { cout << *(iter + i) << " "; } cout << endl; return 0; }
begin()
返回的迭代器指向容器中的第一个元素。
end()
返回的迭代器指向容器中的最后一个元素的下一个位置。
#include <iostream> #include <vector> using namespace std; int main() { vector<char> v1; v1.push_back('h'); v1.push_back('e'); v1.push_back('l'); v1.push_back('l'); v1.push_back('o'); vector<char>::iterator iter1 = v1.begin(); cout << *iter1 << endl; vector<char>::iterator iter2 = v1.end() - 1; cout << *iter2 << endl; return 0; }
如果一个容器为空,则 begin() 和 end() 返回的迭代器相同。
#include <iostream> #include <vector> using namespace std; int main() { vector<char> v; vector<char>::iterator iter1 = v.begin(); vector<char>::iterator iter2 = v.end(); if (iter1 == iter2) { cout << "容器v为空" << endl; } return 0; }
迭代器支持自增、自减操作,于是可以通过如下代码遍历 vector 中的元素。
#include <iostream> #include <vector> using namespace std; int main() { vector<int> v{10, 20, 30, -10, -20, -30}; for (vector<int>::iterator iter = v.begin(); iter != v.end(); iter++) { cout << *iter << " "; } cout << endl; return 0; }
注意:在使用迭代器的过程中,千万不要改变 vector 容器的容量(不要增加或删除 vector 容器中的元素),否则迭代器会失效。
front()
返回头部元素的引用,可以当左值。
back()
返回尾部元素的引用,可以当左值。
#include <iostream> #include <vector> using namespace std; int main() { vector<char> v1; v1.push_back('h'); v1.push_back('e'); v1.push_back('l'); v1.push_back('l'); v1.push_back('o'); cout << "v1.front() = " << v1.front() << endl; cout << "v1.back() = " << v1.back() << endl; v1.front() = 'w'; v1.back() = 'd'; cout << "v1.front() = " << v1.front() << endl; cout << "v1.back() = " << v1.back() << endl; return 0; }
rbegin()
返回一个反向迭代器,指向反向迭代器的第一个元素。
rend()
返回一个反向迭代器,指向反向迭代器的最后一个元素的下一个位置。
#include <iostream> #include <vector> using namespace std; int main() { vector<int> v{10, 20, 30, -10, -20, -30}; for (vector<int>::reverse_iterator riter = v.rbegin(); riter != v.rend(); riter++) { cout << *riter << endl; } return 0; }
vector<int>::iterator iter
可以修改指针的地址,也可以修改指向的元素值。
vector<int>::const_iterator iter
相当于 const char *p
,可以修改指针的地址,但不能修改指向的元素值。const_iterator 对象可以用于 const容器 或 非const容器。
#include <iostream> #include <vector> using namespace std; int main() { const vector<int> v1 = {100, 200, 300}; // const容器 vector<int>::const_iterator iter1 = v1.begin(); // vector本身是const类型,其迭代器也是const类型 *iter1 = 4; // 错误 iter1++; // 正确 vector<int> v2 = {100, 200, 300}; // 非const容器 vector<int>::const_iterator iter2 = v2.begin(); // vector本身是非const类型,其迭代器也是非const类型 *iter2 = 4; // 错误 iter2++; // 正确 return 0; }
const vector<int>::iterator iter
相当于 char * const p
,可以修改指向的元素值,但不能修改指针的地址。const 的 iterator 只能用于 非const 容器。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v = {100, 200, 300}; // 非const容器
const vector<int>::iterator iter = v.begin();
*iter = 4; // 正确
iter++; // 错误
return 0;
}
C++11 引入了两个新函数:cbegin() 和 cend() 返回的都是常量迭代器。
如果容器本身不是 const 类型,但是在某些情况下数据不应该被修改,这时可以通过 cbegin() 和 cend() 返回 const 类型的迭代器,以避免数据被意外修改。
#include <iostream> #include <vector> using namespace std; int main() { vector<int> v = {100, 200, 300}; // 非const容器 for (vector<int>::const_iterator iter = v.cbegin(); iter != v.cend(); iter++) { *iter = 4; // 错误 cout << *iter << endl; } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。