C++:vector容器大全
1、vector数据存储结构:vector的扩充机制:按照当前容器的一倍扩充;vector分配一块连续的内存空间,每次扩充内存空间并不是在原有空间基础上进行叠加,而是重新申请一块更大的内存,并把现有容器中的元素逐个复制,然后销毁旧的内存。【注】:此时,指向旧内存空间的迭代器已经失效,当操作容器时要及时更新迭代器。vector数据结构,连续线性存储。采用3个迭代器_First、_Last、_End指向分配线性空间的不容范围。迭代器变量声明: template<class _Ty, class _A= allocator< _Ty>> class vector { ... protected: iterator _First, _Last, _End; };其中, _First:指向使用空间的头部, _Last:指向使用空间大小(size)的尾部 _End:指向使用空间容量(capacity)的尾部
2、1-1示例: int data[6]={3,5,7,9,2,4}; vector<int>vdata(data, data+6); vdata.push_back(6); ...vector初始化时,内存空间大小为6,存放data的6个元素。当插入第7个元素“6”时,vector利用自己的扩充机制重新申请空间,数据存放结构如图所示:分析:当插入第7个元素,vector原有内存空间不足,于是申请大小为12的内存空间(自增一倍),并将前面已有数据复制到新空间的前部,然后插入第7个元素。此时_Last迭代器指向最后一个有效元素, 而_End迭代器指向vector的最后有效空间位置。利用vector的成员函数size可以获得当前vector的大小,此时为7;利用capacity成员函数获取当前vector的容量,此时为12。
3、vector构造函数原型: template<typename T> explicit ve艘早祓胂ctor();// 默认构造函数,vector对象为空 explicit vector(size_type n, const T& v = T()); // 创建有n个元素的vector对 //象 vector(const vector& x); vector(const_iterator first, const_iterator last);【注】:vector存放的所有对象都是经过初始化的。 如果没有指定存储对象的初始值,则对于内置类型将用0初始化; 对于类类型将调用其默认构造函数进行初始化;【注】:如果无默认初始构造函数,则此时必须提供元素初始值。示例:vector<string> v1; // 创建空容器,其对象类型为string类vector<string> v2(10); // 创建有10个具有初始值(即空串)的string类对象的 容器vector<string> v3(5, "hello"); // 创建有5个值为“hello”的string类对象的容 器vector<string> v4(v3.begin(), v3.end()); // v4是与v3相同的容器(完全复制)
4、ve罕铞泱殳ctor的成员函数:bool empty() const; // 如果容器为空,返回true;否嬴猹缥犴则返回falsesize_typemax_size() const; // 返回容器能容纳的最大元素个数size_type size() const; // 返回容器中元素个数size_type capacity() const;// 容器能够存储的元素个数, //有:capacity() >= size()void reserve(size_type n); // 确保capacity() >= nvoid resize(size_type n, T x = T());// 确保返回后,有:size() == n;如果之前 //size()<n,那么用元素x的值补全。reference front();//返回容器中第一个元素的引用(容器必须非空) reference back(); // 返回容器中最后一个元素的引用(容器必须非空)reference operator[](size_typepos); // 返回下标为pos的元素的引用(下标 //从0开始;如果下标不正确,则属于未 //定义行为。reference at(size_typepos); // 返回下标为pos的元素的引用;如果下标不正 //确,则抛出异常out_of_rangeconst_reference at(size_typepos) const;//返回下标为pos的元素void push_back(const T& x); // 向容器末尾添加一个元素void pop_back();// 弹出容器中最后一个元素(容器必须非空)【注】:下面的插入和删除操作将发生元素的移动,故之前的迭代器可能失效。iterator insert(iterator it, const T& x = T()); // 在插入点元素之前插入元素 //(或者说在插入点插入元素)void insert(iterator it, size_type n, const T& x); //注意迭代器可能不再有效void insert(iterator it, const_iterator first, const_iterator last);iterator erase(iterator it); // 删除指定元素,并返回删除元素后一个元素的位 //置(如果无元素,返回end())iterator erase(iterator first, iterator last); //删除元素后,删除点之后的元素对 //应的迭代器不再有效。void clear() const; // 清空容器,相当于调用erase( begin(), end())void assign(size_type n, const T& x = T());// 赋值,用指定元素序列替换容器 //内所有元素void assign(const_iterator first, const_iterator last);const_iterator begin() const; // 迭代序列iterator begin();const_iterator end() const;iterator end();【注】:任何改变容器大小的操作都可能造成以前的迭代器失效。const_reverse_iteratorrbegin() const;reverse_iteratorrbegin();const_reverse_iterator rend() const;reverse_iterator rend();
5、vector对象的比较:(非成员函数)有六个比较运算符: operator==、 operator!=、 operator<、 operator<=、 operator>、 operator>=。其中, operator==和operator!=:如果vector对象拥有相同的元素个数,并且对应位置的元素全部相等,则两个vector对象相等;否则不等。 operator<、operator<=、operator>、operator>=:采用字典排序策略比较。
6、vector常见操作:①vector头文件: #include <vector>; using namespace std;//命名空间不可少②创建vector对象: vector<int>vec;//声明int一维数组 vector<CvPoint2D32f> Vec32; vector<CvPoint3D64f> Vec3D; vector<vector<CvPoint3D64f>>mVecPoint;//容器的容器, //二维数组③尾部插入数字: vec.push_back(a); Vec32.push_back(cvPoint2D32f(x,y)); Vec3D.push_back(cvPoint3D64f(x,y,z)); mVecPoint.push_back(Vec3D);④使用下标遍历vector容器:下标从0开始; FILE *fp=fopen(“2d.txt”,”wt”); for(inti=0;i<Vec32.size();i++) { fsprintf(fp,”%f %f\n”,Vec32[i].x,Vec32[i].y); } fclose(fp);////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////【注】:遍历容器的容器,遍历二维数组: for (int i=0;i<mVecPoint.size();i++)//先遍历大容器 { for(int j=0;j<mVecPoint [i].size();j++)//再遍历小容器 {cout<<mVecPoint[i][j].x<<mVecPoint[i][j].y<<mVecPoint[i][j].z<<endl; } }定义一个二维的动态数组:vector< vector<int>> Array( 10, vector<int>(0) );for( j = 0; j < 10; j++ ){ for ( i = 0; i< 9; i++ ) { Array[ j ].push_back( i ); }}for( j = 0; j < 10; j++ ){ for(i = 0; i< Array[ j ].size(); i++ ) { cout<< Array[ j ][ i ] << " "; } cout<<endl;}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////⑤使用迭代器访问元素:vector<int>::iterator it;for(it=vec.begin();it!=vec.end();it++) cout<<*it<<endl;⑥插入元素:vec.insert(vec.begin()+i,a);//在第i+1个元素前面插入a,a就变成第i+1个元素了⑦删除元素:vec.erase(vec.begin()+2);删除第三个元素
7、vector中元素数据类型可以为: int、double、string、 CvPoint2D32f、CvPoint2D64f、vector、结构体等;容器中装入自定义的数据类型:// 自定义一个classclass Cmyclass{};// 定义一个存放class的容器vector<Cmyclass>MyVec;vector中存放结构体类型时,常见两种方法:方法一:放入结构体类型变量的副本;方法二:放入指向结构体类型变量的指针;假设结构体类型变量如下:typedef struct student{ char school_name[100]; char gender;//性别 int age; bool is_absent;}StudentInfo;示例:示例:如下图
8、vector排序:①在vector中数据类型为基本类型时,可以调用std::sort()实现升序和降序排序;vector<int> vi ;vi.push_back(1);vi.push_back(3);vi.push_back(0);sort(vi.begin() , vi.end()); //默认:从小到大reverse(vi.begin(),vi.end()) //从大到小////////////////////////////////////////////////////////////////////////////////降序比较:由大到小定义排序比较函数:bool Comp(constint&a,constint&b){ return a>b;}调用时:sort(vec.begin(),vec.end(),Comp),这样就降序排序。
9、②而当vector的数据类型为自定义结构体类型时,怎样实现升序与降序排列呢?有两种方法:方法1:修改结构体或类的定义部分,sort函数实现方法2 :类或结构体外定义函数,使用sort调用函数来实现:如图所示: