概述:
vector容器在头文件<vector>中,它是一段连续的内存空间,也可以说是动态数组,支持随机访问。动态是因为他可以扩展自己的内存空间,每当内存满了之后,想要插入数据时,他会先申请一段(1, 2]倍于当前空间的连续内存,将数据复制过去后销毁旧空间。
声明与初始化容器
//一维容器
vector<int> v; //声明
vector<int> v1(5, 1);//容器大小为5,里面全是1(不给第二个参数默认为0)
vector<int> v2(v.begin(), v.end()); //begin和end是迭代器,可以简单理解为起始下标
vector<int> v3(v);
//vector<存放的数据类型> 容器名(int n, int elem);创建含有n个elem的容器
vector<int> v4(4, 3);
//二维容器
vector<vector<int> > v5(4, vector<int>(5, 1)); //生成四行五列的容器,里面全是1。
vector<vector<int> > v6; 声明
for(int i = 0; i < 5; i++){ //初始化
v6.push_back(v);
}
迭代器:
迭代器的类型为:容器类型<存放元素类型>::iterator,如vector<int>::iterator。可以视为一种指针,其中重载了”*“用来获取值,常见的迭代器有v.begin(),指向容器第一个元素。和v.end(),指向容器最后一个元素再++。
常用函数:
//这是下面的print_v函数,用于输出v中的数据。
void print_v(vector<int> v) {
for (auto i : v) {
cout << i << ' ';
}
cout << endl;
}
assign,赋值操作
assign作用类似于“=”,会先将原容器中的数据清除,之后调用参数给该容器赋值,常用有:assign(v1.begin(), v1.end());调用v1的迭代器来给v赋值,最终v会含有参数一到参数二之间的数据。assign(int n, int elem); 将n个elem数据存入v中(v中有且仅有这n个数据)。
vector<int> v(5, 1);
vector<int> v1(4, 2);
print_v(v);
v.assign(v1.begin(), v1.end());
print_v(v);
v.assign(7, 3);
print_v(v);
容器的容量与大小相关操作
size:
size()用于获取容器的大小,即容器中已经存储了多少元素。
capacity:
capacity()用于获取容器的容量,即容器中可以存储多少元素。
empty:
empty()返回bool类型,用于判断容器是否为空。注意,这里是判断大小是否为空。
resize:
resize()用于重新设置容器的大小,resize(int size);将v的大小设置为size,若size大于v的容量,则扩容为size,并将多出的大小用默认值填充(int类型默认值为0);若size比容量还小,则删去size后面的元素,使得v的大小为size。resize(int size, int elem);作用与只有一个参数的重载函数相同,唯一区别在于,多出的大小用elem填充。
vector<int> v(5, 1); //容量为5,大小为5
cout << "容量为:" << v.capacity() << " 大小为:" << v.size() << endl;
cout << "容器是否为空:" << v.empty() << endl;
v.assign(0, 0); //容量为5,大小为0
cout << "容量为:" << v.capacity() << " 大小为:" << v.size() << endl;
cout << "容器是否为空:" << v.empty() << endl;
v.resize(7); //容量为7,大小为7
print_v(v);
cout << "容量为:" << v.capacity() << " 大小为:" << v.size() << endl;
v.resize(4, 2); //容量为7,大小为4.
print_v(v);
cout << "容量为:" << v.capacity() << " 大小为:" << v.size() << endl;
容器的插入与删除:
尾插法
现在使用的尾插法有两种,push_back和emplace_back。其中push_back(a)会构造一个临时对象a,再将a拷贝或者移动到v的结尾。而emplace_back(a)直接在v的尾部创建a,效率更高(优先使用这个)。
根据迭代器插入
insert的参数是v的迭代器,它可以实现将输入插入到容器中间。insert(const_iterator pos, int elem);在迭代器pos处插入元素elem。insert(const_iterator pos, int n, int elem);在迭代器pos处插入n个元素elem。还可以用emplace,用法与insert基本相同,区别在于emplace一次只能插入一个元素,而且使用emplace时无需构造临时变量。emplace(迭代器,一个或多个元素的构造函数参数)
尾删法
pop_back可以删除容器的最后一个元素。
根据迭代器删除
erase函数根据输入的迭代器进行删除,会返回删除之后后一个元素的迭代器。erase(const_iterator pos);删除迭代器为pos的元素,并返回后一个元素的迭代器。erase(const_iterator start, const_iterator end);删除在迭代器start到end中的所有元素(不删除end),返回end指向元素的迭代器。
vector<int> v(1);
print_v(v);
cout << "容量为:" << v.capacity() << " 大小为:" << v.size() << endl;
v.push_back(3);
print_v(v);
cout << "容量为:" << v.capacity() << " 大小为:" << v.size() << endl;
v.emplace_back(4);
print_v(v);
cout << "容量为:" << v.capacity() << " 大小为:" << v.size() << endl;
//在最前面插入元素5
v.insert(v.begin(), 5);
print_v(v);
cout << "容量为:" << v.capacity() << " 大小为:" << v.size() << endl;
//在最前面插入3个元素2
v.insert(v.begin(), 3, 2);
print_v(v);
cout << "容量为:" << v.capacity() << " 大小为:" << v.size() << endl;
//删除迭代器pos指向的元素
vector<int>::iterator pos = v.begin();
vector<int>::iterator start1 = v.erase(pos);
print_v(v);
//cout << *pos << endl; //注意,执行删除后pos以及之后的迭代器原本指向的地址被销毁了。所以不能调用*pos。
//删除迭代器start1到end1之间的元素(不包括end1)
auto end1 = start1;
end1++;
end1++;
auto it = v.erase(start1, end1);
print_v(v);
cout << *it << endl;
当使用循环删除某个迭代器时的注意事项
循环删除时要注意迭代器的生命周期,不能直接++去删除。而应该像下面这样。
for(vector<int>::iterator it = v.begin(); it != v.end(); ){ //这里不能简单的it++
if(*it == 3){
it = v.erase(it);
}
else{
it++;
}
}
清除容器中的所有元素
clear可以清除容器中所有元素(容量不变,只是大小为0),和erase(v.begin(), v.end())的效果一样。
v.clear();
// v.erase(v.begin(), v.end());
cout << "容量为:" << v.capacity() << " 大小为:" << v.size() << endl;
释放多于的内存空间
由于erase只是用于删除vector中的元素,其内存空间未被释放,可以使用shrink_to__fit来移除vector中多余的内存。
shrink_to_fit函数没有参数,它的作用是清除没有存放数据的内存。如下,刚开始v大小为5,容量为5,使用shrink_to_fit函数后容量=大小,不变。当使用erase清除第一个数据后,容量为5,但大小变为4,此时使用shrink_to_fit会清除多余的容量,使得容量=大小=4。
vector<int> v(5, 1);
cout << "容器的容量为:" << v.capacity() << " 容器的大小为:" << v.size() << endl;
v.shrink_to_fit();
cout << "容器的容量为:" << v.capacity() << " 容器的大小为:" << v.size() << endl;
v.erase(v.begin());
cout << "容器的容量为:" << v.capacity() << " 容器的大小为:" << v.size() << endl;
v.shrink_to_fit();
cout << "容器的容量为:" << v.capacity() << " 容器的大小为:" << v.size() << endl;
获取容器中的元素
最直接的就是通过“[]",也可以用at()获取容器中任意元素。要注意输入的下标不能超过容器的大小。还有front()函数获取第一个元素,back()函数获取最后一个元素。
print_v(v);
cout << "容器的第三个元素为:" << v[2] << endl;
cout << "容器的第二个元素为:" << v.at(1) << endl;
cout << "容器的第一个元素为:" << v.front() << endl;
cout << "容器的最后一个个元素为:" << v.back() << endl;
交换两个容器(包括容量和大小)
swap(vector<int> v1);
vector<int> v(2);
cout << "v的容量为:" << v.capacity() << " 大小为:" << v.size() << endl;
vector<int> v1(3);
cout << "v1的容量为:" << v1.capacity() << " 大小为:" << v1.size() << endl;
v.swap(v1);
cout << "v的容量为:" << v.capacity() << " 大小为:" << v.size() << endl;
cout << "v1的容量为:" << v1.capacity() << " 大小为:" << v1.size() << endl;
重设容器的容量(预留空间)
reserve可以重新设置容器的容量,有计划地设置容器容量可以减少容器扩容的次数,增加效率。reserve(int n);设置容器v的容量为n,若n大于原容器的大小则,保存所有数据到新容器中;若n小于原容器大小,则删除n后面的数据。与resize的区别在于不会填充默认值。
vector<int> v(2);
cout << "v的容量为:" << v.capacity() << " 大小为:" << v.size() << endl;
print_v(v);
v.reserve(3);
cout << "v的容量为:" << v.capacity() << " 大小为:" << v.size() << endl;
print_v(v);