vector 是順序容器的一種。vector 是可變長的動態陣列,支援隨機存取疊代器,所有 STL 演算法都能對 vector 進行操作。要使用 vector,需要包含標頭檔案 vector。
在 vector 容器中,根據下標隨機存取某個元素的時間是常數,在尾部新增一個元素的時間大多數情況下也是常數,總體來說速度很快。
在中間插入或刪除元素時,因為要移動多個元素,因此速度較慢,平均花費的時間和容器中的元素個數成正比。
在 vector 容器中,用一個動態分配的陣列來存放元素,因此根據下標存取某個元素的時間是固定的,與元素個數無關。
vector 容器在實現時,動態分配的儲存空間一般都大於存放元素所需的空間。例如,哪怕容器中只有一個元素,也會分配 32 個元素的儲存空間。這樣做的好處是,在尾部新增一個新元素時不必重新分配空間,直接將新元素寫入適當位置即可。在這種情況下,新增新元素的時間也是常數。
但是,如果不斷新增新元素,多出來的空間就會用完,此時再新增新元素,就不得不重新分配記憶體空間,把原有內容複製過去後再新增新的元素。碰到這種情況,新增新元素所花的時間就不是常數,而是和陣列中的元素個數成正比。
至於在中間插入或刪除元素,必然涉及元素的移動,因此時間不是固定的,而是和元素個數有關。
vector 有很多成員函數,常用的如表 1 所示。
表1:vector中常用的成員函數
成員函數 |
作 用 |
vector() |
無參建構函式,將容器初始化為空 |
vector(int n) |
將容器初始化為有 n 個元素 |
vector(int n, const T & val) |
假定元素的型別是 T,此建構函式將容器初始化為有 n 個元素,每 個元素的值都是 val |
vector(iterator first, iterator last) |
first 和 last 可以是其他容器的疊代器。一般來說,本建構函式初始化的結果就是將 vector 容器的內容變成與其他容器上的區間 [first, last) —致 |
void clear() |
刪除所有元素 |
bool empty() |
判斷容器是否為空 |
void pop_back() |
刪除容器末尾的元素 |
void push_back( const T & val) |
將 val 新增到容器末尾 |
int size() |
返回容器中元素的個數 |
T & front() |
返回容器中第一個元素的參照 |
T & back() |
返回容器中最後一個元素的參照 |
iterator insert(iterator i, const T & val) |
將 val 插入疊代器 i 指向的位置,返回 i |
iterator insert( iterator i, iterator first, iterator last) |
將其他容器上的區間 [first, last) 中的元素插入疊代器 i 指向的位置 |
iterator erase(iterator i) |
刪除疊代器 i 指向的元素,返回值是被刪元素後面的元素的疊代器 |
iterator erase(iterator first, iterator last) |
刪除容器中的區間 [first, last) |
void swap( vector <T> & v) |
將容器自身的內容和另一個同型別的容器 v 互換 |
下面的程式演示了 vector 的基本用法。
#include <iostream>
#include <vector> //使用vector需要包含此標頭檔案
using namespace std;
template <class T>
void PrintVector(const vector <T> & v)
{ //用於輸出vector容器的全部元素的函數模板
typename vector <T>::const_iterator i;
//typename 用來說明 vector <T>::const_iterator 是一個型別,在 Visual Studio 中不寫也可以
for (i = v.begin(); i != v.end(); ++i)
cout << *i << " ";
cout << endl;
}
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
vector <int> v(a, a + 5); //將陣列a的內容放入v
cout << "1) " << v.end() - v.begin() << endl; //兩個隨機疊代器可以相減,輸出:1)5
cout << "2)"; PrintVector(v); //輸出:2)1 2 3 4 5
v.insert(v.begin() + 2, 13); //在 begin()+2 位置插人 13
cout << "3)"; PrintVector(v); //輸出:3)1 2 13 3 4 5
v.erase(v.begin() + 2); //刪除位於 begin()+2 位置的元素
cout << "4)"; PrintVector(v); //輸出:4)1 2 3 4 5
vector<int> v2(4, 100); //v2 有 4 個元素,都是 100
v2.insert(v2.begin(), v.begin() + 1, v.begin() + 3); //將v的一段插入v2開頭
cout << "5)v2:"; PrintVector(v2); //輸出:5)v2:2 3 100 100 100 100
v.erase(v.begin() + 1, v.begin() + 3); //刪除 v 上的一個區間,即 [2,3)
cout << "6)"; PrintVector(v); //輸出:6)1 4 5
return 0;
}
思考題:程式中的 PrintVector 模板演示了將容器的參照作為函數引數的用法。就完成輸出整個容器內容這個功能來說,寫成 PrintVector 模板這樣是比較笨拙的,該模板的適用範圍太窄。有沒有更好的寫法?
vector 還可以巢狀以形成可變長的二維陣列。例如:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<vector<int> > v(3); //v有3個元素,每個元素都是vector<int> 容器
for(int i = 0;i < v.size(); ++i)
for(int j = 0; j < 4; ++j)
v[i].push_back(j);
for(int i = 0;i < v.size(); ++i) {
for(int j = 0; j < v[i].size(); ++j)
cout << v[i][j] << " ";
cout << endl;
}
return 0;
}
程式的輸出結果是:
0 1 2 3
0 1 2 3
0 1 2 3
vector< vector<int> > v(3);
定義了一個 vector 容器,該容器中的每個元素都是一個 vector <int> 容器。即可以認為,v 是一個二維陣列,一共 3 行,每行都是一個可變長的一維陣列。
在 Dev C++ 中,上面寫法中 int 後面的兩個
>
之間需要有空格,否則有的編譯器會把它們當作
>>
運算子,編譯會出錯。