1. 程式人生 > >vector類模板

vector類模板

vector是一個線性順序結構。相當於陣列,但其大小可以不預先指定,並且自動擴充套件。它可以像陣列一樣被操作,由於它的特性我們完全可以將vector 看作動態陣列。

在建立一個vector 後,它會自動在記憶體中分配一塊連續的記憶體空間進行資料儲存,初始的空間大小可以預先指定也可以由vector 預設指定,這個大小即capacity()函式的返回值。當儲存的資料超過分配的空間時vector 會重新分配一塊記憶體塊,但這樣的分配是很耗時的,在重新分配空間時它會做這樣的動作:

首先,vector 會申請一塊更大的記憶體塊;

然後,將原來的資料拷貝到新的記憶體塊中;

其次,銷燬掉原記憶體塊中的物件(呼叫物件的解構函式);

最後,將原來的記憶體空間釋放掉。

    如果vector 儲存的資料量很大時,這樣的操作一定會導致糟糕的效能(這也是vector 被設計成比較容易拷貝的值型別的原因)。所以說vector 不是在什麼情況下效能都好,只有在預先知道它大小的情況下vector 的效能才是最優的。

vector 的特點:

(1) 指定一塊如同陣列一樣的連續儲存,但空間可以動態擴充套件。即它可以像陣列一樣操作,並且可以進行動態操作。通常體現在push_back() pop_back() 

(2) 隨機訪問方便,它像陣列一樣被訪問,即支援[ ] 操作符和vector.at()

(3) 節省空間,因為它是連續儲存,在儲存資料的區域都是沒有被浪費的,但是要明確一點

vector 大多情況下並不是滿存的,在未儲存的區域實際是浪費的。

(4) 在內部進行插入、刪除操作效率非常低,這樣的操作基本上是被禁止的。Vector 被設計成只能在後端進行追加和刪除操作,其原因是vector 內部的實現是按照順序表的原理。

(5) 只能在vector 的最後進行push pop ,不能在vector 的頭進行push pop 

(6) 當動態新增的資料超過vector 預設分配的大小時要進行記憶體的重新分配、拷貝與釋放,這個操作非常消耗效能。 所以要vector 達到最優的效能,最好在建立vector 時就指定其空間大小。

       Vectors 包含著一系列連續儲存的元素

,其行為和陣列類似。訪問Vector中的任意元素或從末尾新增元素都可以在常量級時間複雜度內完成,而查詢特定值的元素所處的位置或是在Vector中插入元素則是線性時間複雜度。

1.Constructors 建構函式

vector<int> v1; //構造一個空的vector

vector<int> v1( 5, 42 ); //構造了一個包含5個值為42的元素的Vector

2.Operators 對vector進行賦值或比較

C++ Vectors能夠使用標準運算子: ==, !=, <=, >=, <, 和 >.

要訪問vector中的某特定位置的元素可以使用 [] 操作符.

兩個vectors被認為是相等的,如果:

    1.它們具有相同的容量

    2.所有相同位置的元素相等.

vectors之間大小的比較是按照詞典規則.

3.assign() 對Vector中的元素賦值

語法:

void assign( input_iterator start, input_iterator end );

// 將區間[start, end)的元素賦到當前vector

void assign( size_type num, const TYPE &val );

// 賦num個值為val的元素到vector中,這個函式將會清除掉為vector賦值以前的內容。

4.at() 返回指定位置的元素

語法:

TYPE at( size_type loc );//差不多等同v[i];但比v[i]安全;

5.back() 返回最末一個元素

6.begin() 返回第一個元素的迭代器

7.capacity() 返回vector所能容納的元素數量(在不重新分配記憶體的情況下)

8.clear() 清空所有元素

9.empty() 判斷Vector是否為空(返回true時為空)

10.end() 返回最末元素的迭代器(譯註:實指向最末元素的下一個位置)

11.erase() 刪除指定元素

語法:

iterator erase( iterator loc );//刪除loc處的元素

iterator erase( iterator start, iterator end );//刪除start和end之間的元素

12.front() 返回第一個元素的引用

13.get_allocator() 返回vector的記憶體分配器

14.insert() 插入元素到Vector中

語法:

iterator insert( iterator loc, const TYPE &val );

//在指定位置loc前插入值為val的元素,返回指向這個元素的迭代器,

void insert( iterator loc, size_type num, const TYPE &val );

//在指定位置loc前插入num個值為val的元素

void insert( iterator loc, input_iterator start, input_iterator end );

//在指定位置loc前插入區間[start, end)的所有元素

15.max_size() 返回Vector所能容納元素的最大數量(上限)

16.pop_back() 移除最後一個元素

17.push_back() 在Vector最後新增一個元素

18.rbegin() 返回Vector尾部的逆迭代器

19.rend() 返回Vector起始的逆迭代器

20.reserve() 設定Vector最小的元素容納數量

//為當前vector預留至少共容納size個元素的空間

21.resize() 改變Vector元素數量的大小

語法:

void resize( size_type size, TYPE val );

//改變當前vector的大小為size,且對新建立的元素賦值val

22.size() 返回Vector元素數量的大小

23.swap() 交換兩個Vector

語法:

void swap( vector &from );

Vector用法 :

1.宣告:

一個vector類似於一個動態的一維陣列。

vector<int> a; //宣告一個元素為int型別的vector a

vectot<MyType> a; //宣告一個元素為MyType型別的vector a

這裡的宣告的a包含0個元素,既a.size()的值為0,但它是動態的,其大小會隨著資料的插入和刪除改變而改變。

vector<int> a(100, 0); //這裡宣告的是一個已經存放了100個0的整數vector

你可以用以下的幾種方法宣告一個 vector 物件:

vector<float> v(5, 3.25); //初始化有5 個元素,其值都是3.25

vector<float> v_new1(v);

vector<float> v_new2 = v;

vector<float> v_new3(v.begin(), v.end());

這四個vector 物件是相等的,可以用operator==來判斷。

2.向量操作

常用函式:

size_t size(); // 返回vector的大小,即包含的元素個數

void pop_back(); // 刪除vector末尾的元素,vector大小相應減一

void push_back(); //用於在vector的末尾新增元素

T back(); // 返回vector末尾的元素

void clear(); // 將vector清空,vector大小變為0

其他訪問方式:

cout<<a[5]<<endl;

cout<<a.at(5)<<endl;

以上區別在於後者在訪問越界時會丟擲異常,而前者不會。

3.遍歷

(1). for(vector<datatype>::iterator it=a.begin(); it!=a.end();it++)

cout<<*it<<endl;

(2). for(int i=0;i<a.size;i++)

cout<<a[i]<<endl;

現在想得到容器中能儲存的最大元素數量就可以用 vector 類的成員函式max_size():

vector<shape>::size_type max_size = my_shapes.max_size();

當前容器的實際尺寸 --- 已有的元素個數用size():

vector<shape>::size_type size = my_shapes.size();

就像size_type 描述了vector 尺寸的型別,value_type 說明了其中儲存的物件的型別:

cout << “value type: “ << typeid(vector<float>::value_type).name();

輸出:

value type: float

可以用capacity()來取得vector 中已分配記憶體的元素個數:

vector<int> v;

vector<int>::size_type capacity = v.capacity();

vector 類似於陣列,可以使用下標[]訪問:

vector<int> v(10);

v[0] = 101;

注意到這裡預先給10 個元素分配了空間。你也可以使用vector 提供的插入函式來動態的擴

展容器。成員函式push_back()就在vector 的尾部添加了一個元素:

v.push_back(3);

也可以用insert()函式完成同樣的工作:

v.insert(v.end(), 3);

這裡insert()成員函式需要兩個引數:一個指向容器中指定位置的迭代器(iterator),一個待插

入的元素。insert()將元素插入到迭代器指定元素之前。

現在對迭代器(Iterator)做點解釋。Iterator 是指標(pointer)的泛化,iterator 要求定義

operator*,它返回指定型別的值。Iterator 常常和容器聯絡在一起。例子:

vector<int> v(3);

v[0] = 5;

v[1] = 2;

v[2] = 7;

vector<int>::iterator first = v.begin();

vector<int>::iterator last = v.end();

while (first != last)

cout << *first++ << “ “;

上面程式碼的輸出是:

5 2 7

begin()返回的是vector 中第一個元素的iterator,而end()返回的並不是最後一個元素的

iterator,而是past the last element。在STL 中叫past-the-end iterator