如果需要線性、長度可變的資料容器,可以使用 vector
,這需要包含 vector
標頭檔:
#include <vector>
技術上來說,vector
是個類別模版(class template),不過使用上,只需要知道,vector
可以裝載指定型態的資料。例如,建立一個可裝載 int
的 vector<int>
:
vector<int> number;
這會建立一個空的 vector<int>
,如果想在建立容器時裝載指定的元素,可以使用清單初始化(list initialization)或者初始器(Initializer):
vector<int> number = {10, 20, 30};
vector<double> score{85.5, 78.2, 63.0};
想要循序地走訪 vector
中的元素,可以使用 for range 語法,例如:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> number = {10, 20, 30};
for(auto n : number) {
cout << n << endl;
}
return 0;
}
透過 []
指定索引可以存取特定位置的元素,例如:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> number = {10, 20, 30};
for(int i = 0; i < number.size(); i++) {
cout << number[i] << endl;
}
return 0;
}
可以從 vector
的 size
方法得知元素的個數,empty
方法可以得知是否為空,front
方法可以取得第一個元素,back
方法可以取得最後一個元素,想要新增元素,可以使用 push_back
、insert
方法,想取出最後一個元素可以用 pop_back
,clear
可以清空 vector
等。
底下會顯示 9 到 0 的數字:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> number;
for(int i = 0; i < 10; i++) {
number.push_back(i);
}
while(!number.empty()) {
int n = number.back();
number.pop_back();
cout << n << endl;
}
return 0;
}
建立 vector
時可以指定初始的長度,每個元素會被初始為指定型態的零值,例如底下會建立長度為 10 的 vector
,元素初值都是 0:
vector<int> v1(10);
也可以在指定初始長度的同時,指定每個元素的初值,例如底下會建立長度為 10 的 vector
,元素初值都是 5:
vector<int> v1(10, 5);
vector
可以使用另一個 vector
作為引數來建構,例如以 v1
作為引數來建構 v2
:
vector<int> v1 = {10, 20, 30};
vector<int> v2(v1);
這會將 vector
的元素複製給被指定的 vector
;vector
可以指定給另一 vector
,這也會將 vector
的元素複製給被指定的 vector
,例如:
vector<int> v1 = {10, 20, 30};
vector<int> v2 = v1;
若要指定來源 vector
的某個範圍建構出新的 vector
,必須指定起始位置的 iterator
與結束位置的iterator
,例如底下從索引 2 開始走訪至尾端的元素,用以建立新的 vector
:
vector<int> v1 = {10, 20, 30, 40, 50};
vector<int> v2(v1.begin() + 2, v1.end()); // 包含 30, 40, 50
在上頭,begin
與 end
方法分別傳回起始位置的 vector<int>::iterator
與結束位置的 vector<int>::iterator
,可以把它們看成代表首個元素與最後一個元素的位置,對它們進行 +
或 -
運算,表示元素的位移量,操作上很像指標,至於是不是真的指標,要看底層的實作而定。
就 API 的設計來說,不建議將 begin
、end
方法的傳回值看成是指標,而建議將之看成迭代器(iterator),這些迭代器重載了相關的運算子,令其看來像是指標操作,因為容器相關的程式庫,為基於這類操作協定,令提供的 API 具有通用性。
若要使用迭代器來走訪元素,例如,先前的 for range 語法,若要使用 begin
與 end
方法,可以搭配 for
迴圈,例如:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> number = {10, 20, 30};
for(vector<int>::iterator it = number.begin();
it != number.end();
it++) {
auto n = *it;
cout << n << endl;
}
return 0;
}
類似地,若要使用陣列的元素來建構 vector
,可以透過以下的方式:
int number[] = {10, 20, 30, 40, 50};
vector<int> v(begin(number) + 2, end(number)); // 包含 30, 40, 50
如果打算對 vector
進行排序、尋找、反轉等操作,可以使用包含 algorithm
標頭檔:
#include <algorithm>
一些操作會使用到迭代器,例如下面這個程式直接示範了排序、尋找、反轉等操作:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> number = {30, 12, 55, 31, 98, 11, 41, 80, 66, 21};
// 排序
sort(number.begin(), number.end());
for(auto n : number) {
cout << n << " ";
}
cout << endl;
cout << "輸入搜尋值:";
int search = 0;
cin >> search;
vector<int>::iterator it = find(number.begin(), number.end(), search);
cout << (it != number.end() ? "找到" : "沒有")
<< "搜尋值"
<< endl;
// 反轉
reverse(number.begin(), number.end());
for(auto n : number) {
cout << n << " ";
}
cout << endl;
return 0;
}
執行結果:
11 12 21 30 31 41 55 66 80 98
輸入搜尋值:22
沒有搜尋值
98 80 66 55 41 31 30 21 12 11