C++ STL之vector詳解




C++ STL之vector詳解

Vectors
   vector是C++標準模板庫中的部分內容,它是一個多功能的,能夠操作多種數據結構和算法的模板類和函數庫。vector之所以被認爲是一個容器,是因爲它能夠像容器一樣存放各種類型的對象,簡單地說,vector是一個能夠存放任意類型的動態數組,能夠增加和壓縮數據。爲了可以使用vector,必須在你的頭文件中包含下面的代碼:#include <vector>
構造函數。


  Vectors 包含着一系列連續存儲的元素,其行爲和數組類似。訪問Vector中的任意元素或從末尾添加元素都可以在常量級時間複雜度內完成,而查找特定值的元素所處的位置或是在Vector中插入元素則是線性時間複雜度。


函數列表如下:
Constructors 構造函數 
Operators 對vector進行賦值或比較 
assign() 對Vector中的元素賦值 
at() 返回指定位置的元素 
back() 返回最末一個元素 
begin() 返回第一個元素的迭代器 
capacity() 返回vector所能容納的元素數量(在不重新分配內存的情況下) 
clear() 清空所有元素 
empty() 判斷Vector是否爲空(返回true時爲空) 
end() 返回最末元素的迭代器(譯註:實指向最末元素的下一個位置) 
erase() 刪除指定元素 
front() 返回第一個元素 
get_allocator() 返回vector的內存分配器 
insert() 插入元素到Vector中 
max_size() 返回Vector所能容納元素的最大數量(上限) 
pop_back() 移除最後一個元素 
push_back() 在Vector最後添加一個元素 
rbegin() 返回Vector尾部的逆迭代器 
rend() 返回Vector起始的逆迭代器 
reserve() 設置Vector最小的元素容納數量 
resize() 改變Vector元素數量的大小 
size() 返回Vector元素數量的大小 
swap() 交換兩個Vector

////////////////////////////////////////////////////////////////////////////
                               函數詳細說明
構造函數
語法: 
vector();
vector( size_type num, const TYPE &val );
vector( const vector &from );
vector( input_iterator start, input_iterator end );


C++ Vectors可以使用以下任意一種參數方式構造: 
無參數 - 構造一個空的vector, 
數量(num)和值(val) - 構造一個初始放入num個值爲val的元素的Vector 
vector(from) - 構造一個與vector from 相同的vector 
迭代器(start)和迭代器(end) - 構造一個初始值爲[start,end)區間元素的Vector(注:半開區間). 
舉例,下面這個實例構造了一個包含5個值爲42的元素的Vector
vector<int> v1( 5, 42 );
運算符
語法: 
v1 == v2
v1 != v2
v1 <= v2
v1 >= v2
v1 < v2
v1 > v2 
v[]
C++ Vectors能夠使用標準運算符: ==, !=, <=, >=, <, 和 >. 要訪問vector中的某特定位置的元素可以使用 [] 操作符. 
兩個vectors被認爲是相等的,如果: 
它們具有相同的容量 
所有相同位置的元素相等. 
vectors之間大小的比較是按照詞典規則. 


assign函數 

語法: 
void assign( input_iterator start, input_iterator end );
void assign( size_type num, const TYPE &val );
assign() 函數要麼將區間[start, end)的元素賦到當前vector,或者賦num個值爲val的元素到vector中.這個函數將會清除掉爲vector賦值以前的內容.


at函數 
語法: 
TYPE at( size_type loc );
at() 函數 返回當前Vector指定位置loc的元素的引用. at() 函數 比 [] 運算符更加安全, 因爲它不會讓你去訪問到Vector內越界的元素. 例如, 考慮下面的代碼:
vector<int> v( 5, 1 );
for( int i = 0; i < 10; i++ ) {
cout << "Element " << i << " is " << v[i] << endl;
}
這段代碼訪問了vector末尾以後的元素,這將可能導致很危險的結果.以下的代碼將更加安全: 
vector<int> v( 5, 1 );
for( int i = 0; i < 10; i++ ) {
cout << "Element " << i << " is " << v.at(i) << endl;
}
取代試圖訪問內存裏非法值的作法,at() 函數能夠辨別出訪問是否越界並在越界的時候拋出一個異常out_of_range.


back 函數 
語法: 
TYPE back();
back() 函數返回當前vector最末一個元素的引用.例如: 
vector<int> v;
for( int i = 0; i < 5; i++ ) {
v.push_back(i);
}
cout << "The first element is " << v.front() 
     << " and the last element is " << v.back() << endl;
這段代碼產生如下結果:
The first element is 0 and the last element is 4


begin 函數 
語法: 
iterator begin();
begin()函數返回一個指向當前vector起始元素的迭代器.例如,下面這段使用了一個迭代器來顯示出vector中的所有元素:
vector<int> v1( 5, 789 );
vector<int>::iterator it;
for( it = v1.begin(); it != v1.end(); it++ )
cout << *it << endl;


capacity 函數 
語法: 
size_type capacity();
capacity() 函數 返回當前vector在重新進行內存分配以前所能容納的元素數量.


clear 函數 
語法: 
void clear();
clear()函數刪除當前vector中的所有元素.


empty 函數 
語法: 
bool empty();
如果當前vector沒有容納任何元素,則empty()函數返回true,否則返回false.例如,以下代碼清空一個vector,並按照逆序顯示所有的元素:
vector<int> v;
for( int i = 0; i < 5; i++ ) {
    v.push_back(i);
}
while( !v.empty() ) {
    cout << v.back() << endl;
    v.pop_back();
}


end 函數 
語法: 
iterator end();
end() 函數返回一個指向當前vector末尾元素的下一位置的迭代器.注意,如果你要訪問末尾元素,需要先將此迭代器自減1.


erase 函數 
語法: 
iterator erase( iterator loc );
iterator erase( iterator start, iterator end );
erase函數要麼刪作指定位置loc的元素,要麼刪除區間[start, end)的所有元素.返回值是指向刪除的最後一個元素的下一位置的迭代器.例如:
// 創建一個vector,置入字母表的前十個字符
vector<char> alphaVector;
for( int i=0; i < 10; i++ )
    alphaVector.push_back( i + 65 );
int size = alphaVector.size();

vector<char>::iterator startIterator;
vector<char>::iterator tempIterator;

for( int i=0; i < size; i++ )
{
    tartIterator = alphaVector.begin();
    alphaVector.erase( startIterator );

    // Display the vector
    for( tempIterator = alphaVector.begin(); tempIterator != alphaVector.end(); tempIterator++ )
    cout << *tempIterator;
    cout << endl;

這段代碼將會顯示如下輸出:

BCDEFGHIJ
CDEFGHIJ
DEFGHIJ
EFGHIJ
FGHIJ
GHIJ
HIJ
IJ
J

front 函數 
語法: 
TYPE front();
front()函數返回當前vector起始元素的引用


get_allocator 函數 
語法: 
allocator_type get_allocator();
get_allocator() 函數返回當前vector的內存分配器.在STL裏面一般不會調用new或者alloc來分配內存,而且通過一個allocator對象的相關方法來分配.
示例:vector<int>v3( 3, 1, v2.get_allocator( ));//把V2的內存分配器作爲一個參數參與構造V3。這樣,它們兩個用一個內存分配器了。


insert 函數 
語法: 
iterator insert( iterator loc, const TYPE &val );
void insert( iterator loc, size_type num, const TYPE &val );
void insert( iterator loc, input_iterator start, input_iterator end );
insert() 函數有以下三種用法: 
在指定位置loc前插入值爲val的元素,返回指向這個元素的迭代器, 
在指定位置loc前插入num個值爲val的元素 
在指定位置loc前插入區間[start, end)的所有元素 . 
舉例: 
//創建一個vector,置入字母表的前十個字符
vector<char> alphaVector;
for( int i=0; i < 10; i++ )
alphaVector.push_back( i + 65 );
//插入四個C到vector中
vector<char>::iterator theIterator = alphaVector.begin();
alphaVector.insert( theIterator, 4, 'C' );
//顯示vector的內容
for( theIterator = alphaVector.begin(); theIterator != alphaVector.end(); theIterator++ )
cout << *theIterator;
這段代碼將顯示: 
CCCCABCDEFGHIJ


max_size 函數 
語法: 
size_type max_size();
max_size() 函數返回當前vector所能容納元素數量的最大值(譯註:包括可重新分配內存). 


pop_back 
語法: 
void pop_back();
pop_back()函數刪除當前vector最末的一個元素,例如:

vector<char> alphaVector;
for( int i=0; i < 10; i++ )
    alphaVector.push_back( i + 65 );

int size = alphaVector.size();
vector<char>::iterator theIterator;
for( int i=0; i < size; i++ ) {
alphaVector.pop_back();
for( theIterator = alphaVector.begin(); theIterator != alphaVector.end(); theIterator++ )
      cout << *theIterator;
cout << endl;
}

這段代碼將顯示以下輸出:

ABCDEFGHI
ABCDEFGH
ABCDEFG
ABCDEF
ABCDE
ABCD
ABC
AB
A

push_back 函數 
語法: 
void push_back( const TYPE &val );
push_back()添加值爲val的元素到當前vector末尾


rbegin 函數 
語法: 
reverse_iterator rbegin();
rbegin函數返回指向當前vector末尾的逆迭代器.(譯註:實際指向末尾的下一位置,而其內容爲末尾元素的值,詳見逆代器相關內容)
示例:
vector<int>v1;
for(int i=1;i<=5;i++)
{
    v1.push_back(i);
}
vector<int>::reverse_iterator pos;
pos=v1.rbegin();
cout<<*pos<<" ";
pos++;
cout<<*pos<<endl;
輸出結果爲:5 4


rend 函數 
語法: 
reverse_iterator rend();
rend()函數返回指向當前vector起始位置的逆迭代器. 
示例:
vector<int>v1;
for(int i=1;i<=5;i++)
{
    v1.push_back(i);
}
vector<int>::reverse_iterator pos;
pos=v1.rend();
pos--;
cout<<*pos<<" ";
pos--;
cout<<*pos<<endl;
輸出結果爲:1 2


reserve 函數 
語法: 
void reserve( size_type size );
reserve()函數爲當前vector預留至少共容納size個元素的空間.(譯註:實際空間可能大於size)


resize 函數 
語法: 
void resize( size_type size, TYPE val );
resize() 函數改變當前vector的大小爲size,且對新創建的元素賦值val

resize 與reserve的區別
    reserve是容器預留空間,但並不真正創建元素對象,在創建對象之前,不能引用容器內的元素,因此當加入新的元素時,需要用push_back()/insert()函數。
    resize是改變容器的大小,並且創建對象,因此,調用這個函數之後,就可以引用容器內的對象了,因此當加入新的元素時,用operator[]操作符,或者用迭代器來引用元素對象。再者,兩個函數的形式是有區別的,reserve函數之後一個參數,即需要預留的容器的空間;resize函數可以有兩個參數,第一個參數是容器新的大小,第二個參數是要加入容器中的新元素,如果這個參數被省略,那麼就調用元素對象的默認構造函數。
初次接觸這兩個接口也許會混淆,其實接口的命名就是對功能的絕佳描述,resize就是重新分配大小,reserve就是預留一定的空間。這兩個接口即存在差別,也有共同點。下面就它們的細節進行分析。
     爲實現resize的語義,resize接口做了兩個保證:
            一是保證區間[0, new_size)範圍內數據有效,如果下標index在此區間內,vector[indext]是合法的。
             二是保證區間[0, new_size)範圍以外數據無效,如果下標index在區間外,vector[indext]是非法的。
     reserve只是保證vector的空間大小(capacity)最少達到它的參數所指定的大小n。在區間[0, n)範圍內,如果下標是index,vector[index]這種訪問有可能是合法的,也有可能是非法的,視具體情況而定。
     resize和reserve接口的共同點是它們都保證了vector的空間大小(capacity)最少達到它的參數所指定的大小。
因兩接口的源代碼相當精簡,以至於可以在這裏貼上它們:
void resize(size_type new_size) { resize(new_size, T()); }
void resize(size_type new_size, const T& x) {
    if (new_size < oldsize) 
      erase(oldbegin + new_size, oldend); // erase區間範圍以外的數據,確保區間以外的數據無效
    else
      insert(oldend, new_size - oldsize, x); // 填補區間範圍內空缺的數據,確保區間內的數據有效
示例:
#include<iostream>
#include<vector>
using namespace std;
void main()
{
    vector<int>v1;
for(int i=1;i<=3;i++)
{
    v1.push_back(i);
}
v1.resize(5,8);//多出的兩個空間都初始化爲8,
for(i=0;i<v1.size();i++)//resize與reserver並不會刪除原先的元素以釋放空間
{
     cout<<v1[i]<<" ";
}
cout<<endl;
v1.reserve(7);// 新元素還沒有構造,
    for(i=0;i<7;i++)
{
     cout<<v1[i]<<" ";//當i>4,此時不能用[]訪問元素 
}
cout<<endl;
cout<<v1.size()<<endl;
cout<<v1.capacity()<<endl;
}
輸出結果爲:
1 2 3 8 8
1 2 3 8 8 -842150451 -842150451
5
7


size
 函數 

語法: 
size_type size();
size() 函數返回當前vector所容納元素的數目 


swap 函數 
語法: 
void swap( vector &from );
swap()函數交換當前vector與vector from的元素
示例:
     vector<int>v1,v2;
     for(int i=1;i<=3;i++)
     {
v1.push_back(i);
        v2.push_back(i);
     }
v2.push_back(4);
     v2.push_back(5);
     v1.swap(v2);
     for(int j=0;j<v1.size();j++)
     {
cout<<v1[j]<<" ";
     }
     cout<<endl;
     for(int k=0;k<v2.size();k++)
     {
cout<<v2[k]<<" ";
     }
     cout<<endl;
輸出結果爲:
1 2 3 4 5
1 2 3

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章