C++中vector使用詳細說明 (轉)

轉自:http://blog.chinaunix.net/uid-26000296-id-3785610.htmlhtml

http://www.cnblogs.com/mr-wid/archive/2013/01/22/2871105.htmlios

1、向量的介紹
    向量 vector 是一種對象實體, 可以容納許多其餘類型相同的元素, 所以又被稱爲容器。 與string相同, vector 同屬於STL(Standard Template Library, 標準模板庫)中的一種自定義的數據類型, 能夠廣義上認爲是數組的加強版。
    
    在使用它時, 須要包含頭文件 vector, #include<vector>
    
    vector 容器與數組相比其優勢在於它可以根據須要隨時自動調整自身的大小以便容下所要放入的元素。此外, vector 也提供了許多的方法來對自身進行操做。
    
    算法

 


2、向量的聲明及初始化
    vector 型變量的聲明以及初始化的形式也有許多, 經常使用的有如下幾種形式:數組

複製代碼
        vector<int> a ;                                //聲明一個int型向量a
        vector<int> a(10) ;                            //聲明一個初始大小爲10的向量
        vector<int> a(10, 1) ;                         //聲明一個初始大小爲10且初始值都爲1的向量
        vector<int> b(a) ;                             //聲明並用向量a初始化向量b
        vector<int> b(a.begin(), a.begin()+3) ;        //將a向量中從第0個到第2個(共3個)做爲向量b的初始值
複製代碼

        
    除此以外, 還能夠直接使用數組來初始化向量:數據結構

        int n[] = {1, 2, 3, 4, 5} ;
        vector<int> a(n, n+5) ;              //將數組n的前5個元素做爲向量a的初值
        vector<int> a(&n[1], &n[4]) ;        //將n[1] - n[4]範圍內的元素做爲向量a的初值

 


        
        
3、元素的輸入及訪問
    元素的輸入和訪問能夠像操做普通的數組那樣, 用cin>>進行輸入, cout<<a[n]這樣進行輸出:
    示例:數據結構和算法

複製代碼
 1     #include<iostream>
 2     #include<vector>
 3 
 4     using namespace std ;
 5 
 6     int main()
 7     {
 8         vector<int> a(10, 0) ;      //大小爲10初值爲0的向量a
 9 
10         //對其中部分元素進行輸入
11         cin >>a[2] ;
12         cin >>a[5] ;
13         cin >>a[6] ;
14 
15         //所有輸出
16         int i ;
17         for(i=0; i<a.size(); i++)
18             cout<<a[i]<<" " ;
19 
20         return 0 ;
21     }
複製代碼

    
    在元素的輸出上, 還可使用遍歷器(又稱迭代器)進行輸出控制。在 vector<int> b(a.begin(), a.begin()+3) ; 這種聲明形式中, (a.begin()、a.begin()+3) 表示向量起始元素位置到起始元素+3之間的元素位置。(a.begin(), a.end())則表示起始元素和最後一個元素以外的元素位置。
    向量元素的位置便成爲遍歷器, 同時, 向量元素的位置也是一種數據類型, 在向量中遍歷器的類型爲: vector<int>::iterator。 遍歷器不但表示元素位置, 還能夠再容器中先後移動。
    
    在上例中講元素所有輸出部分的代碼就能夠改寫爲:函數

    //所有輸出
    vector<int>::iterator t ;
    for(t=a.begin(); t!=a.end(); t++)
        cout<<*t<<" " ;

        
    *t 爲指針的間接訪問形式, 意思是訪問t所指向的元素值。
    
    大數據

 


4、向量的基本操做ui

複製代碼
      1>. a.size()                 //獲取向量中的元素個數

2>. a.empty() //判斷向量是否爲空

3>. a.clear() //清空向量中的元素

4>. 複製 a = b ; //將b向量複製到a向量中

5>. 比較 保持 ==!=>>=<<= 的慣有含義 ; 如: a == b ; //a向量與b向量比較, 相等則返回1

6>. 插入 - insert ①、 a.insert(a.begin(), 1000); //將1000插入到向量a的起始位置前 ②、 a.insert(a.begin(), 3, 1000) ; //將1000分別插入到向量元素位置的0-2處(共3個元素) ③、 vector<int> a(5, 1) ; vector<int> b(10) ; b.insert(b.begin(), a.begin(), a.end()) ; //將a.begin(), a.end()之間的所有元素插入到b.begin()前

7>. 刪除 - erase ①、 b.erase(b.begin()) ; //將起始位置的元素刪除 ②、 b.erase(b.begin(), b.begin()+3) ; //將(b.begin(), b.begin()+3)之間的元素刪除

8>. 交換 - swap b.swap(a) ; //a向量與b向量進行交換
複製代碼

 


        
        
5、二維向量
    與數組相同, 向量也能夠增長維數, 例如聲明一個m*n大小的二維向量方式能夠像以下形式:spa

        vector< vector<int> > b(10, vector<int>(5));        //建立一個10*5的int型二維向量

 
    在這裏, 實際上建立的是一個向量中元素爲向量的向量。一樣能夠根據一維向量的相關特性對二維向量進行操做。
    
    :

複製代碼
 1     #include<iostream>
 2     #include<vector>
 3 
 4     using namespace std ;
 5 
 6     int main()
 7     {
 8         vector< vector<int> > b(10, vector<int>(5, 0)) ;
 9 
10         //對部分數據進行輸入
11         cin>>b[1][1] ;
12         cin>>b[2][2] ;
13         cin>>b[3][3];
14 
15         //所有輸出
16         int m, n ;
17         for(m=0; m<b.size(); m++)           //b.size()獲取行向量的大小
18         {
19             for(n=0; n<b[m].size(); n++)    //獲取向量中具體每一個向量的大小
20                 cout<<b[m][n]<<" " ;
21             cout<<"\n" ;
22         }
23 
24         return 0;
25     }
複製代碼

    
    一樣, 按照這樣的思路咱們還能夠建立更多維的向量, 不過維數太多會讓向量變得難以靈活控制, 三維以上的向量還需酌情使用。

___________________________________________________________________________________________________________________________________________________________________

1. 在C++中的詳細說明vector是C++標準模板庫中的部份內容,它是一個多功能的,可以操做多種數據結構和算法的模板類和函數庫。vector之因此被認爲是一個容器,是由於它可以像容器同樣存放各類類型的對象,簡單地說,vector是一個可以存聽任意類型的動態數組,可以增長和壓縮數據。2. 使用vector,必須在你的頭文件中包含下面的代碼:  #include vector屬於std命名域的,所以須要經過命名限定,以下完成你的代碼:  using std::vector;  vector vInts;  或者連在一塊兒,使用全名:      std::vector vInts;  建議使用全局的命名域方式:    using namespace std;3. 初始化   vector                 // 建立一個空的vector。vector c1(c2)          // 複製一個vectorvector c(n)            // 建立一個vector,含有n個數據,數據均已缺省構造產生vector c(n, elem)      // 建立一個含有n個elem拷貝的vectorvector c(beg,end)      // 建立一個含有n個elem拷貝的vector4. 析構函數c.~vector ()           // 銷燬全部數據,釋放內存5. 成員函數c.assign(beg,end)c.assign(n,elem)  將[beg; end)區間中的數據賦值給c。將n個elem的拷貝賦值給c。c.at(idx)  傳回索引idx所指的數據,若是idx越界,拋出out_of_range。c.back()      // 傳回最後一個數據,不檢查這個數據是否存在。c.begin()     // 傳回迭代器中的第一個數據地址。c.capacity()  // 返回容器中數據個數。c.clear()     // 移除容器中全部數據。c.empty()     // 判斷容器是否爲空。c.end()       // 指向迭代器中末端元素的下一個,指向一個不存在元素。c.erase(pos)  // 刪除pos位置的數據,傳回下一個數據的位置。c.erase(beg,end)  //刪除[beg,end)區間的數據,傳回下一個數據的位置。c.front()     // 傳回第一個數據。get_allocator // 使用構造函數返回一個拷貝。c.insert(pos,elem)    // 在pos位置插入一個elem拷貝,傳回新數據位置。c.insert(pos,n,elem)  // 在pos位置插入n個elem數據。無返回值。c.insert(pos,beg,end) // 在pos位置插入在[beg,end)區間的數據。無返回值。  c.max_size()       // 返回容器中最大數據的數量。c.pop_back()       // 刪除最後一個數據。c.push_back(elem)  // 在尾部加入一個數據。c.rbegin()         // 傳回一個逆向隊列的第一個數據。c.rend()           // 傳回一個逆向隊列的最後一個數據的下一個位置。c.resize(num)      // 從新指定隊列的長度。c.reserve()        // 保留適當的容量。c.size()           // 返回容器中實際數據的個數。c1.swap(c2)swap(c1,c2)        // 將c1和c2元素互換。同上操做。operator[]         // 返回容器中指定位置的一個引用。6. 用法示例:6.1. 建立一個vectorvector容器提供了多種建立方法,下面介紹幾種經常使用的。建立一個Widget類型的空的vector對象:  vector vWidgets;  建立一個包含500個Widget類型數據的vector:  vector vWidgets(500);  建立一個包含500個Widget類型數據的vector,而且都初始化爲0:  vector vWidgets(500, Widget(0));  建立一個Widget的拷貝:  vector vWidgetsFromAnother(vWidgets);  向vector添加一個數據  vector添加數據的缺省方法是push_back()。    push_back()函數表示將數據添加到vector的尾部,並按須要來分配內存。例如:向vector中添加10個數據,須要以下編寫代碼:  for(int i= 0;i<10; i++) {    vWidgets.push_back(Widget(i));  }6.2 獲取vector中指定位置的數據  vector裏面的數據是動態分配的,使用push_back()的一系列分配空間經常決定於文件或一些數據源。    若是想知道vector存放了多少數據,可使用empty()。    獲取vector的大小,可使用size()。例如,若是想獲取一個vector v的大小,但不知道它是否爲空,或者已經包含了數據,若是爲空想設置爲-1,你可使用下面的代碼實現:  int nSize = v.empty() ? -1 : static_cast(v.size());  6.3 訪問vector中的數據使用兩種方法來訪問vector。一、 vector::at()二、 vector::operator[]  operator[]主要是爲了與C語言進行兼容。它能夠像C語言數組同樣操做。    但at()是咱們的首選,由於at()進行了邊界檢查,若是訪問超過了vector的範圍,將拋出一個例外。    因爲operator[]容易形成一些錯誤,全部咱們不多用它,下面進行驗證一下:  分析下面的代碼:  vector v;  v.reserve(10);      for(int i=0; i<7; i++) {    v.push_back(i);  }      try {int iVal1 = v[7];    // not bounds checked - will not throw    int iVal2 = v.at(7);    // bounds checked - will throw if out of range  }         catch(const exception& e) {    cout << e.what();  }  6.3 刪除vector中的數據vector可以很是容易地添加數據,也能很方便地取出數據,一樣vector提供了erase(),pop_back(),clear()來刪除數據,當刪除數據時,應該知道要刪除尾部的數據,或者是刪除全部數據,仍是個別的數據。Remove_if()算法 若是要使用remove_if(),須要在頭文件中包含以下代碼::  #include Remove_if()有三個參數:  一、 iterator _First:指向第一個數據的迭代指針。  二、 iterator _Last:指向最後一個數據的迭代指針。  三、 predicate _Pred:一個能夠對迭代操做的條件函數。  6.4 條件函數條件函數是一個按照用戶定義的條件返回是或否的結果,是最基本的函數指針,或是一個函數對象。這個函數對象須要支持全部的函數調用操做,重載operator()()操做。remove_if()是經過unary_function繼承下來的,容許傳遞數據做爲條件。例如,假如想從一個vector中刪除匹配的數據,若是字串中包含了一個值,從這個值開始,從這個值結束。首先應該創建一個數據結構來包含這些數據,相似代碼以下:#include enum findmodes {  FM_INVALID = 0,  FM_IS, FM_STARTSWITH, FM_ENDSWITH, FM_CONTAINS};typedef struct tagFindStr { UINT iMode; CString szMatchStr;} FindStr;typedef FindStr* LPFINDSTR;  而後處理條件判斷:class FindMatchingString : public std::unary_function<cstring, bool=""> {public: FindMatchingString(const LPFINDSTR lpFS) : m_lpFS(lpFS) {} bool operator()(CString& szStringToCompare) const {  bool retVal = false;      switch (m_lpFS->iMode) {  case FM_IS: {    retVal = (szStringToCompare == m_lpFDD->szMatchStr);    break;  }  case FM_STARTSWITH: {    retVal = (szStringToCompare.Left(m_lpFDD->szMatchStr.GetLength())      == m_lpFDD->szWindowTitle);    break;  }  case FM_ENDSWITH: {    retVal = (szStringToCompare.Right(m_lpFDD->szMatchStr.GetLength())      == m_lpFDD->szMatchStr);  break;  }  case FM_CONTAINS: {    retVal = (szStringToCompare.Find(m_lpFDD->szMatchStr) != -1);    break;  }   }   return retVal;  }private: LPFINDSTR m_lpFS;};經過這個操做你能夠從vector中有效地刪除數據:    FindStr fs;  fs.iMode = FM_CONTAINS;  fs.szMatchStr = szRemove;  vs.erase(std::remove_if(vs.begin(), vs.end(), FindMatchingString(&fs)), vs.end());  Remove(),remove_if()等全部的移出操做都是創建在一個迭代範圍上的,不能操做容器中的數據。因此在使用remove_if(),實際上操做的時容器裏數據的上面的。看到remove_if()其實是根據條件對迭代地址進行了修改,在數據的後面存在一些殘餘的數據,那些須要刪除的數據。剩下的數據的位置可能不是原來的數據,但他們是不知道的。調用erase()來刪除那些殘餘的數據。注意上面例子中經過erase()刪除remove_if()的結果和vs.enc()範圍的數據。7. 綜合例子://---------------------------------------------------------------------------#include #pragma hdrstop#include "Unit1.h"//---------------------------------------------------------------------------#pragma package(smart_init)#pragma resource "*.dfm"TForm1 *Form1;#include #include using namespace std;struct STResult{    double Time;    double Xp;    double Yp;    int id;};//---------------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner)    : TForm(Owner){}vector ResultVector;void __fastcall test(){    //test    //vector ResultVector;    STResult stritem;    stritem.Time = .1;    stritem.Xp = .1;    stritem.Yp = .1;    stritem.id = 1;    ResultVector.push_back( stritem );}//---------------------------------------------------------------------------void __fastcall TForm1::Button1Click(TObject *Sender){    test();    assert(ResultVector[0].id == 1);}//---------------------------------------------------------------------------

相關文章
相關標籤/搜索