750
人物
STL之二:vector容器用法詳解
vector類稱作向量類,它實現了動態數組,用於元素數量變化的對象數組。像數組一樣,vector類也用從0開始的下標表示元素的位置;但和數組不同的是,當vector對象創建後,數組的元素個數會隨著vector對象元素個數的增大和縮小而自動變化。
vector類常用的函數如下所示:
1.構造函數
- vector():創建一個空vector
- vector(int nSize):創建一個vector,元素個數為nSize
- vector(int nSize,const t& t):創建一個vector,元素個數為nSize,且值均為t
- vector(const vector&):複製構造函數
- vector(begin,end):複製[begin,end)區間內另一個數組的元素到vector中
2.增加函數
- void push_back(const T& x):向量尾部增加一個元素X
- iterator insert(iterator it,const T& x):向量中迭代器指向元素前增加一個元素x
- iterator insert(iterator it,int n,const T& x):向量中迭代器指向元素前增加n個相同的元素x
- iterator insert(iterator it,const_iterator first,const_iterator last):向量中迭代器指向元素前插入另一個相同類型向量的[first,last)間的數據
3.刪除函數
- iterator erase(iterator it):刪除向量中迭代器指向元素
- iterator erase(iterator first,iterator last):刪除向量中[first,last)中元素
- void pop_back():刪除向量中最後一個元素
- void clear():清空向量中所有元素
4.遍曆函數
- reference at(int pos):返回pos位置元素的引用
- reference front():返回首元素的引用
- reference back():返回尾元素的引用
- iterator begin():返回向量頭指針,指向第一個元素
- iterator end():返回向量尾指針,指向向量最後一個元素的下一個位置
- reverse_iterator rbegin():反向迭代器,指向最後一個元素
- reverse_iterator rend():反向迭代器,指向第一個元素之前的位置
5.判斷函數
- bool empty() const:判斷向量是否為空,若為空,則向量中無元素
6.大小函數
- int size() const:返回向量中元素的個數
- int capacity() const:返回當前向量張紅所能容納的最大元素值
- int max_size() const:返回最大可允許的vector元素數量值
7.其他函數
- void swap(vector&):交換兩個同類型向量的數據
- void assign(int n,const T& x):設置向量中第n個元素的值為x
- void assign(const_iterator first,const_iterator last):向量中[first,last)中元素設置成當前向量元素
示例:
1.初始化示例
#include "stdafx.h" #include<iostream> #include<vector> using namespace std; class A { //空類 }; int _tmain(int argc, _TCHAR* argv[]) { //int型vector vector<int> vecInt; //float型vector vector<float> vecFloat; //自定義類型,保存類A的vector vector<A> vecA; //自定義類型,保存指向類A的指針的vector vector<A*> vecPointA; return 0; }
// vectorsample.cpp : 定義控製台應用程序的入口點。 // #include "stdafx.h" #include<iostream> #include<vector> using namespace std; class A { //空類 }; int _tmain(int argc, _TCHAR* argv[]) { //int型vector,包含3個元素 vector<int> vecIntA(3); //int型vector,包含3個元素且每個元素都是9 vector<int> vecIntB(3,9); //複製vecIntB到vecIntC vector<int> vecIntC(vecIntB); int iArray[]={2,4,6}; //創建vecIntD vector<int> vecIntD(iArray,iArray+3); //打印vectorA,此處也可以用下麵注釋內的代碼來輸出vector中的數據 /*for(int i=0;i<vecIntA.size();i++) { cout<<vecIntA[i]<<" "; }*/ cout<<"vecIntA:"<<endl; for(vector<int>::iterator it = vecIntA.begin();it!=vecIntA.end();it++) { cout<<*it<<" "; } cout<<endl; //打印vecIntB cout<<"VecIntB:"<<endl; for(vector<int>::iterator it = vecIntB.begin() ;it!=vecIntB.end();it++) { cout<<*it<<" "; } cout<<endl; //打印vecIntC cout<<"VecIntB:"<<endl; for(vector<int>::iterator it = vecIntC.begin() ;it!=vecIntC.end();it++) { cout<<*it<<" "; } cout<<endl; //打印vecIntD cout<<"vecIntD:"<<endl; for(vector<int>::iterator it = vecIntD.begin() ;it!=vecIntD.end();it++) { cout<<*it<<" "; } cout<<endl; return 0; }
程序的運行結果如下:

上麵的代碼用了4種方法建立vector並對其初始化
2.增加及獲得元素示例:
// vectorsample.cpp : 定義控製台應用程序的入口點。 // #include "stdafx.h" #include<iostream> #include<vector> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { //int型vector,包含3個元素 vector<int> vecIntA; //插入1 2 3 vecIntA.push_back(1); vecIntA.push_back(2); vecIntA.push_back(3); int nSize = vecIntA.size(); cout<<"vecIntA:"<<endl; //打印vectorA,方法一: for(int i=0;i<nSize;i++) { cout<<vecIntA[i]<<" "; } cout<<endl; //打印vectorA,方法二: for(int i=0;i<nSize;i++) { cout<<vecIntA.at(i)<<" "; } cout<<endl; //打印vectorA,方法三: for(vector<int>::iterator it = vecIntA.begin();it!=vecIntA.end();it++) { cout<<*it<<" "; } cout<<endl; return 0; }
上述代碼對一個整形向量類進行操作,先定義一個整形元素向量類,然後插入3個值,並用3種不同的方法輸出,程序運行結果如下:

// vectorsample.cpp : 定義控製台應用程序的入口點。 // #include "stdafx.h" #include<iostream> #include<vector> using namespace std; class A { public: int n; public: A(int n) { this->n = n; } }; int _tmain(int argc, _TCHAR* argv[]) { //int型vector,包含3個元素 vector<A> vecClassA; A a1(1); A a2(2); A a3(3); //插入1 2 3 vecClassA.push_back(a1); vecClassA.push_back(a2); vecClassA.push_back(a3); int nSize = vecClassA.size(); cout<<"vecClassA:"<<endl; //打印vecClassA,方法一: for(int i=0;i<nSize;i++) { cout<<vecClassA[i].n<<" "; } cout<<endl; //打印vecClassA,方法二: for(int i=0;i<nSize;i++) { cout<<vecClassA.at(i).n<<" "; } cout<<endl; //打印vecClassA,方法三: for(vector<A>::iterator it = vecClassA.begin();it!=vecClassA.end();it++) { cout<<(*it).n<<" "; } cout<<endl; return 0; }
上述代碼通過定義元素為類的向量,通過插入3個初始化的類,並通過3種方法輸出,運行結果如下:
// vectorsample.cpp : 定義控製台應用程序的入口點。 // #include "stdafx.h" #include<iostream> #include<vector> using namespace std; class A { public: int n; public: A(int n) { this->n = n; } }; int _tmain(int argc, _TCHAR* argv[]) { //int型vector,包含3個元素 vector<A*> vecClassA; A *a1 = new A(1); A *a2 = new A(2); A *a3 = new A(3); //插入1 2 3 vecClassA.push_back(a1); vecClassA.push_back(a2); vecClassA.push_back(a3); int nSize = vecClassA.size(); cout<<"vecClassA:"<<endl; //打印vecClassA,方法一: for(int i=0;i<nSize;i++) { cout<<vecClassA[i]->n<<"\t"; } cout<<endl; //打印vecClassA,方法二: for(int i=0;i<nSize;i++) { cout<<vecClassA.at(i)->n<<"\t"; } cout<<endl; //打印vecClassA,方法三: for(vector<A*>::iterator it = vecClassA.begin();it!=vecClassA.end();it++) { cout<<(**it).n<<"\t"; } cout<<endl; delete a1; delete a2;delete a3; return 0; }
上述代碼通過定義元素為類指針的向量,通過插入3個初始化的類指針,並通過3種方法輸出指針指向的類,運行結果如下:
3.修改元素示例
修改元素的方法主要有三種:1.通過數組修改,2.通過引用修改,3.通過迭代器修改
// vectorsample.cpp : 定義控製台應用程序的入口點。 // #include "stdafx.h" #include<iostream> #include<vector> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { //int型vector,包含3個元素 vector<int> vecIntA; //插入1 2 3 vecIntA.push_back(1); vecIntA.push_back(2); vecIntA.push_back(3); int nSize = vecIntA.size(); //通過引用修改vector cout<<"通過數組修改,第二個元素為8:"<<endl; vecIntA[1]=8; cout<<"vecIntA:"<<endl; //打印vectorA for(vector<int>::iterator it = vecIntA.begin();it!=vecIntA.end();it++) { cout<<*it<<" "; } cout<<endl; //通過引用修改vector cout<<"通過引用修改,第二個元素為18:"<<endl; int &m = vecIntA.at(1); m=18; cout<<"vecIntA:"<<endl; //打印vectorA for(vector<int>::iterator it = vecIntA.begin();it!=vecIntA.end();it++) { cout<<*it<<" "; } cout<<endl; //通過迭代器修改vector cout<<"通過迭代器修改,第二個元素為28"<<endl; vector<int>::iterator itr = vecIntA.begin()+1; *itr = 28; cout<<"vecIntA:"<<endl; //打印vectorA for(vector<int>::iterator it = vecIntA.begin();it!=vecIntA.end();it++) { cout<<*it<<" "; } cout<<endl; return 0; }
程序運行結果如下:

4.刪除向量示例
刪除向量主要通過erase和pop_back,示例代碼如下
// vectorsample.cpp : 定義控製台應用程序的入口點。 // #include "stdafx.h" #include<iostream> #include<vector> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { //int型vector,包含3個元素 vector<int> vecIntA; //循環插入1 到10 for(int i=1;i<=10;i++) { vecIntA.push_back(i); } vecIntA.erase(vecIntA.begin()+4); cout<<"刪除第5個元素後的向量vecIntA:"<<endl; //打印vectorA for(vector<int>::iterator it = vecIntA.begin();it!=vecIntA.end();it++) { cout<<*it<<"\t"; } cout<<endl; //刪除第2-5個元素 vecIntA.erase(vecIntA.begin()+1,vecIntA.begin()+5); cout<<"刪除第2-5個元素後的vecIntA:"<<endl; //打印vectorA for(vector<int>::iterator it = vecIntA.begin();it!=vecIntA.end();it++) { cout<<*it<<"\t"; } cout<<endl; //刪除最後一個元素 vecIntA.pop_back(); cout<<"刪除最後一個元素後的vecIntA:"<<endl; //打印vectorA for(vector<int>::iterator it = vecIntA.begin();it!=vecIntA.end();it++) { cout<<*it<<"\t"; } cout<<endl; return 0; }
程序運行結果如下:

3.進一步理解vector,如下圖所示:

當執行代碼vector<int> v(2,5)時,在內存裏建立了2個整形元素空間,值是5.當增加一個元素時,原有的空間由2個編程4個整形元素空間,並把元素1放入第3個整形空間,第4個空間作為預留空間。當增加元素2時,直接把值2放入第4個空間。當增加元素3時,由於原有向量中沒有預留空間,則內存空間由4個變為8個整形空間,並把值放入第5個內存空間。
總之,擴大新元素時,如果超過當前的容量,則容量會自動擴充2倍,如果2倍容量仍不足,則繼續擴大2倍。本圖是直接在原空間基礎上畫的新增空間,其實要複雜的多,包括重新配置、元素移動、釋放原始空間的過程。因此對vector容器而言,當增加新的元素時,有可能很快完成(直接存在預留空間中),有可能稍慢(擴容後再放新元素);對修改元素值而言是較快的;對刪除元素來說,弱刪除尾部元素較快,非尾部元素稍慢,因為牽涉到刪除後的元素移動。
4.綜合示例
// vectorsample.cpp : 定義控製台應用程序的入口點。 // #include "stdafx.h" #include<iostream> #include<vector> #include<string> using namespace std; class Student { public: string m_strNO; string m_strName; string m_strSex; string m_strDate; public: Student(string strNO,string strName,string strSex,string strDate) { m_strNO = strNO; m_strName = strName; m_strSex = strSex; m_strDate = strDate; } void Display() { cout<<m_strNO<<"\t"; cout<<m_strName<<"\t"; cout<<m_strSex<<"\t"; cout<<m_strDate<<"\t"; } }; class StudCollect { vector<Student> m_vStud; public: void Add(Student &s) { m_vStud.push_back(s); } Student* Find(string strNO) { bool bFind = false; int i; for(i = 0;i < m_vStud.size();i++) { Student& s = m_vStud.at(i); if(s.m_strNO == strNO) { bFind = true; break; } } Student *s = NULL; if(bFind) s = &m_vStud.at(i); return s; } }; int _tmain(int argc, _TCHAR* argv[]) { Student s1("1001","zhangsan","boy","1988-10-10"); Student s2("1002","lisi","boy","1988-8-25"); Student s3("1003","wangwu","boy","1989-2-14"); StudCollect s; s.Add(s1); s.Add(s2); s.Add(s3); Student *ps = s.Find("1002"); if(ps) ps->Display(); return 0; }
代碼運行實例如下:

最後更新:2017-04-04 07:03:36