閱讀750 返回首頁    go 人物


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

  上一篇:go Solr搜索服務架構圖
  下一篇:go 【設計模式】【用DOM4J模擬spring實現簡單工廠】