1. 程式人生 > 其它 >C++ vector容器的多種遍歷方式

C++ vector容器的多種遍歷方式

技術標籤:學習札記c++容器stl

vector容器的遍歷方式

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;

template<typename Type> //型別模板 
Type v_print(const Type val)
{
	cout<<val<<" "; //有了模板val可以使用多種型別 
	return val;
}

int v_assign(int &i) 
{
	i=rand()%10;    //標頭檔案<cstdlib>
	return i;
} 

int main(void)
{
	int a[]={0,1,2,3,4,5,6,7,8,9};
	int len=sizeof(a)/sizeof(a[0]); 

//方式一:普通for迴圈 
	cout<<"一、普通for迴圈:"<<endl; 
	vector <int> v1;
	v1.reserve(len); //預留空間後才能用下標法賦值,否則崩潰 
	for (int i=0;i<len;i++) v1[i]=a[i];
	cout<<"當前vector的大小:"<<v1.size()<<endl;  //雖然成功賦值但size()依舊為0 
	for (int i=0;i<len;i++) cout<<v1[i]<<" "; cout<<endl;
	
	v1.resize(len); //resize可行但僅為測試。不如直接宣告 v1(10); 
	for (int i=0;i<len;i++) v1[i]=a[i];
	cout<<"當前vector的大小:"<<v1.size()<<endl;
	for (int i=0;i<len;i++) cout<<v1.at(i)<<" "; cout<<endl<<endl;

//方式二:for auto迴圈 
	cout<<"二、for auto迴圈:"<<endl; 
	vector <int> v2;
	for (auto arr:a) v2.push_back(arr);
	for (auto vec:v2) cout<<vec<<" "; cout<<endl<<endl;
	/*顯而易見,for auto比方式一更簡潔 */ 
	
//方式三:迭代器
	//迭代器 iterator 是一種用於遍歷容器元素的資料型別
	//vector<T>::iterator iter;//定義一個T型別vector的迭代器
	//操作符 * 訪問迭代器所指向的元素的值,與指標類似 
	//只讀迭代器用 vector<T>::const_iterator const_iter;
	cout<<"三、迭代器方式:"<<endl; 
	vector <int> v3(10);
	for(vector<int>::size_type ix=0;ix!=v3.size();ix++) v3[ix]=rand()%10;
	//vector<int>::size_type 等價於unsigned int
	cout<<"for語句:"<<endl;
	vector<int>::iterator it=v3.begin(); 
	for(;it!=v3.end();it++) cout<<*it<<" "; cout<<endl;
	//或者寫成一行: for(vector<int>::iterator it=v3.begin();it!=v3.end();it++)...
	cout<<"while語句:"<<endl;
	it=v3.begin(); //迭代器指回到起始位置 
	while (it!=v3.end()) cout<<*(it++)<<" "; cout<<endl; //一定要it++,不能++it 
	cout<<"for auto語句:"<<endl;
	for (auto it=v3.begin();it!=v3.end();it++) cout<<*it<<" "; cout<<endl<<endl;
	
//方式四:for_each() 必須標頭檔案<algorithm>
	cout<<"四、for_each()方式:"<<endl; 
	vector <int> v4(10);
	cout<<"呼叫庫函式或自定義函式:"<<endl;
    for_each(v4.begin(), v4.end(), v_assign); //呼叫自定義函式v_assign()隨機賦個一位整數 
	for_each(v4.begin(), v4.end(), v_print<int>); //呼叫自定義函式v_print()列印元素 
	cout<<endl;
	cout<<"直接使用Lambda匿名函式:"<<endl;
	for_each(v4.begin(), v4.end(), [](const int& val)->void{cout<<val<<" ";});
	cout<<endl<<endl;		//關於Lambda函式另找時間討論學習

//方式五:transform() 必須標頭檔案<algorithm>
	cout<<"五、transform()方式:"<<endl; 
	vector <int> v5(10);
	transform(v5.begin(),v5.end(),v5.begin(),v_assign);
	transform(v5.begin(),v5.end(),v5.begin(),v_print<int>); cout<<endl;
	transform(v5.begin(),v5.end(),v5.begin(),[](const int& val)->int{cout<<val<<" ";});
	cout<<endl<<endl;

//方式六:copy()+輸出流迭代器
	cout<<"六、copy()+輸出流迭代器:"<<endl; 
	vector <string> v6(10,"a");	
	ostream_iterator<string> output(cout," "); //輸出流迭代器 ostream_iterator
	copy(v6.begin(),v6.end(),output); cout<<endl<<endl;
	//或者寫成一行:copy(v6.begin(), v6.end(), ostream_iterator<string>(cout, " "));

	//最後測試一下用 v_print()輸出string
	for_each(v6.begin(), v6.end(), v_print<string>); cout<<endl;
	transform(v6.begin(), v6.end(), v6.begin(), v_print<string>); 
	
	return 0;
}

輸出結果:

一、普通for迴圈:
當前vector的大小:0
0 1 2 3 4 5 6 7 8 9
當前vector的大小:10
0 1 2 3 4 5 6 7 8 9

二、for auto迴圈:
0 1 2 3 4 5 6 7 8 9

三、迭代器方式:
for語句:
1 7 4 0 9 4 8 8 2 4
while語句:
1 7 4 0 9 4 8 8 2 4
for auto語句:
1 7 4 0 9 4 8 8 2 4

四、for_each()方式:
呼叫庫函式或自定義函式:
5 5 1 7 1 1 5 2 7 6
直接使用Lambda匿名函式:
5 5 1 7 1 1 5 2 7 6

五、transform()方式:
1 4 2 3 2 2 1 6 8 5
1 4 2 3 2 2 1 6 8 5

六、copy()+輸出流迭代器:
a a a a a a a a a a

a a a a a a a a a a
a a a a a a a a a a
--------------------------------
Process exited after 0.4503 seconds with return value 0
請按任意鍵繼續. . .

vector[i]和vector.at(i)區別

後者比前者多了對i是否越界的檢查,如i>=size()會丟擲std::out_of_range異常,建議使用後者。

for_each()和transform()的區別

1.前者靠形參&引用方式傳遞可以是void型函式,後者必須有return來返回值;
2.後者還有5個引數的形式,比如可以將兩個源容器的元素合併,並將結果寫入目標區間。

其他vector相關文章:

C++ vector宣告和賦值的相關函式