知识点3:Vector 容器
概述:
单端动态数组容器,随机访问迭代器,本质:类模板。
案例:
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
//1、实例化vector容器对象
vector<int> v;
//2、插入数据
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
//3、遍历
//3.1定义一个迭代器指向第一个元素
vector<int>::iterator it = v.begin();
for(;it!=v.end();it++){
//it是迭代器。*it是迭代器指向的内容(int)
cout<<*it<<" ";
}
cout<<endl;
return 0;
}
容器提供的方法:
1、构造
template<typename T>
void printvector(vector<T> &v){
typename::std::vector<T>::iterator it = v.begin();
for(;it!=v.end();it++){
//it是迭代器。*it是迭代器指向的内容(int)
cout<<*it<<" ";
}
cout<<endl;
}
#if 0
vector<T> v; //采用模板实现类实现,默认构造函数
vector(v.begin(), v.end());//将 v[begin(), end())区间中的元素拷贝给本身。
vector(n, elem);//构造函数将 n 个 elem 拷贝给本身。
vector(const vector &vec);//拷贝构造函数。
#endif
void test01(void){
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
printvector(v);//v=123
vector<int> v1(v.begin(), v.end());
printvector(v1);//v1=123
vector<int> v2(3,1);//v2=111
printvector(v2);
vector<int> v3(v2);
printvector(v3);//v3=111
}
2、赋值和取值操作
#if 0
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);//将 n 个 elem 拷贝赋值给本身。
vector& operator=(const vector &vec);//重载等号操作符
swap(vec);// 将 vec 与本身的元素互换。
at(int idx); //返回索引 idx 所指的数据,如果 idx 越界,抛出 out_of_range 异常。
operator[];//返回索引 idx 所指的数据,越界时,运行直接报错
front();//返回容器中第一个数据元素
back();//返回容器中最后一个数据元素
#endif
void test02(void){
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
printvector(v);//v=123
vector<int> v1=v;
printvector(v1);//v1=123
vector<char> v2;
v2.assign(5,'h');
printvector(v2);//v2=hhhhh
vector<char> v3;
v3.assign(v2.begin(),v2.end());
printvector(v3);//v3=hhhhh
cout<<"v.at(1)="<<v.at(1)<<" "<<"v[1]:"<<v[1]<<endl;
cout<<"v容器第一个元素:"<<v.front()<<" "<<"v容器最后一个元素:"<<v.back()<<endl;
}
3、插入删除操作
#if 0
insert(const_iterator pos, int count,ele);//迭代器指向位置 pos 插入 count个元素 ele.
push_back(ele); //尾部插入元素 ele
pop_back();//删除最后一个元素
erase(const_iterator start, const_iterator end);//删除迭代器从 start 到 end 之间的元素
erase(const_iterator pos);//删除迭代器指向的元素
clear();//删除容器中所有元素
#endif
void test03(void){
vector<int> v;
v.push_back(1);
v.push_back(3);
v.push_back(4);
printvector(v);//v=134
v.insert(v.begin()+1,1,2);
printvector(v);//v=1234
v.insert(v.end(),4,5);
printvector(v);//v=12345555
v.pop_back();
printvector(v);//v=1234555
v.erase(v.begin(),v.begin()+4);
printvector(v);//v=555
v.clear();
printvector(v);//v=
}
4、大小操作
4.1vector容器动态扩容(未雨绸缪)机制:
1、每次扩容是之前的2倍。
2、第一次扩容
如果是尾插或者插入1个元素,开辟空间=1
如果是插入多个元素,开辟控制空间=多个元素个数
3、insert小于实际大小时候会扩充初始时实际大小的二倍,当大于实际大小 的按指定大小扩容
//验证动态扩容机制
void test04(void){
vector<int> v;
cout<<"容量="<<v.capacity()<<"实际大小"<<v.size()<<endl;
vector<int>::iterator it;
for(int i=0;i<1000;i++){
v.push_back(1);
if(it != v.begin()){
cout<<"容量="<<v.capacity()<<"实际大小"<<v.size()<<endl;
it=v.begin();
}
}
}
//验证动态扩容机制
void test05(void){
vector<int> v;
v.insert(v.begin(),3,1);
cout<<"容量="<<v.capacity()<<"实际大小"<<v.size()<<endl;
vector<int>::iterator it;
for(int i=0;i<1000;i++){
v.insert(v.end(),1,1);
if(it != v.begin()){
cout<<"容量="<<v.capacity()<<"实际大小"<<v.size()<<endl;
it=v.begin();
}
}
}
4.2修改容器长度及预留空间
#if 0
size();//返回容器中元素的个数
empty();//判断容器是否为空
resize(int num);//重新指定容器的长度为 num,若容器变长,则以默认值填充新位置。
如果容器变短,则末尾超出容器长度的元素被删除。
resize(int num, elem);//重新指定容器的长度为 num,若容器变长,则以 elem 值填
充新位置。如果容器变短,则末尾超出容器长>度的元素被删除。
capacity();//容器的容量
reserve(int len);//容器预留 len 个元素长度,预留位置不初始化,元素不可访问。
#endif
void test06(void){
vector<int> v;
if(v.empty()){
cout<<"空"<<endl;
}
for(int i=0;i<10;i++){
v.push_back(i);
}
printvector(v);//v=0-9
v.resize(12);
printvector(v);//v=0-9 0 0
v.resize(2);
printvector(v);//v=0 1
v.resize(5,9);
printvector(v);//v=0 1 9 9 9
vector<int> v1;
v1.reserve(10);//预留10个容量
cout<<"容量="<<v1.capacity()<<"实际大小"<<v1.size()<<endl;
for(int i=0;i<5;i++){
v1.push_back(i);
}
printvector(v1);//v=0 1 2 3 4(前五个已初始化可访问,剩余未初始化不可访问)
}
5、巧用swap收缩预留空间(了解)
#include <iostream>
#include <vector>
using namespace std;
void printvector(vector<int> &v){
vector<int>::iterator it = v.begin();
for(;it!=v.end();it++){
//it是迭代器。*it是迭代器指向的内容(int)
cout<<*it<<" ";
}
cout<<endl;
}
int main(int argc, char *argv[])
{
vector<int> v;
v.reserve(10);
for(int i=0;i<8;i++){
v.push_back(i);
}
cout<<"容量="<<v.capacity()<<"实际="<<v.size()<<endl;
// v.resize(8);//无法修改预留空间的大小
vector<int>(v).swap(v);//用v实例化匿名对象,并将匿名对象和v 中内容交换
cout<<"容量="<<v.capacity()<<"实际="<<v.size()<<endl;
printvector(v);
return 0;
}
6、vector保存自定义数据类型(了解)
#include <iostream>
#include <vector>
using namespace std;
class Person
{
friend void printvector(vector<Person> &v);
private:
int age;
string name;
public:
Person() {}
Person(int age,string name) {
this->age=age;
this->name=name;
}
};
void printvector(vector<Person> &v){
vector<Person>::iterator it = v.begin();
for(;it!=v.end();it++){
//it是迭代器。*it是迭代器指向的内容(Person)
cout<<(*it).name<<" "<<(*it).age<<endl;
}
}
int main(int argc, char *argv[])
{
vector<Person> v;
v.push_back(Person(20,"zixuan"));
v.push_back(Person(20,"hongye"));
printvector(v);
return 0;
}
7、容器嵌套容器(了解)
#include <iostream>
#include <vector>
using namespace std;
void printvector(vector<vector<int>> &v){
vector<vector<int>>::iterator it = v.begin();
for(;it!=v.end();it++){//遍历的是容器
//it是迭代器。*it是迭代器指向的内容(vector<int>)
vector<int>::iterator mit = (*it).begin();
for(;mit!=(*it).end();mit++){
//mit是迭代器。*mit是迭代器指向的内容(int)
cout<<(*mit)<<" ";
}
cout<<endl;
}
}
int main(int argc, char *argv[])
{
vector<int> v1;
for(int i=1;i<4;i++){
v1.push_back(i);
}
vector<int> v2;
for(int i=11;i<14;i++){
v2.push_back(i);
}
vector<vector<int>> v;//v保存的是v1,v2
v.push_back(v1);
v.push_back(v2);
printvector(v);
return 0;
}