一. 什么是vector
vector為“變長數組”,即長度根據需要而自動改變的數組。
頭文件:
#include <vector>using namespace std;
單獨定義一個vector:vector<typename> name
,相當于一維數組 name[SIZE] ,其長度可以根據需要變化,比較節省空間。
和一維數組一樣,這里的 typename 可以是任何基本類型,如 int, double, char, 結構體等,也可以是STL標準容器,如vector, set, queue等。
在C++11之前,如果 typename 是一個STL容器,定義時需要在 >> 符號之間加空格,否則編譯器會將它視為移位操作,導致編譯錯誤。
例子:
vector<int> name;vector<char> name;vector<node> name; //node為結構體類型vector<vector<int>> name; //二維數組,兩個維都可以變長//二維數組,一維長度固定為100,另一維變長,name[0]~name[99]每一個都是一個vector容器vector<int> name[100];
二. vector的初始化
- 不帶參數的構造函數初始化
//初始化一個size為0的空vectorvector<int> abc;
- 帶參數的構造函數初始化
//初始化size,但每個元素值為默認值vector<int> abc(10); //初始化了10個默認值為0的元素//初始化size,并且設置初始值vector<int> cde(10,1); //初始化了10個值為1的元素
- 通過復制同類型的vector初始化
vector<int> a(5,1);//通過復制a初始化vector<int> b(a);
- 通過復制 [begin,end) 區間內另一個數組的元素到vector中來進行初始化
int a[5] = {1,2,3,4,5};//通過數組a的地址初始化,注意地址是 [0, 5)vector<int> b(a, a+5);
三. vector容器內元素的訪問
-
通過下標訪問
和訪問普通數組一樣,對一個定義為vector<typename> name
的vector容器來說,直接訪問 name[index] 即可(如name[0], name[1])。這里的下標是從0到name.size() - 1,訪問這個范圍外的元素可能會運行出錯。 -
通過迭代器訪問
迭代器(iterator)可以理解為一種類似指針的東西,其定義為:vector<typename>::iterator it;
這里 it 就是一個vector<typename>::iterator
型的變量,可以通過*it
來訪問vector中的元素。
在常用STL容器中,只有在vector和string中,才允許使用 name.begin() + 3 這種迭代器加上整數的寫法。
//name.begin()為取name的首元素地址,it指向這個地址vector<int>::iterator it = name.begin();for(int i = 0; i < name.size(); i++){printf("%d ", *(it + i)); //輸出name[i]}//循環條件使用it != name.end(),不支持it < name.end()寫法for(vector<int>::iterator it = name.begin(); it != name.end(); it++){printf("%d ", *it);}
四. vector常用函數
1. 添加
- void push_back(const T& x):在vector尾部添加一個元素x
- iterator insert(iterator it, const T& x):向vector中迭代器 it 處的前方插入一個元素x
- iterator insert(iterator it, int n, const T& x):向vector中迭代器 it 處的前方插入 n 個相同的元素x
- iterator insert(iterator it, const_iterator first, const_iterator last):向vector中迭代器 it 處插入另一個相同類型vector的 [first,last) 間的數據
vector<int> name;name.push_back(1); //1vector<int>::iterator it = name.begin();name.insert(it, 2); //2 1name.insert(it, 2, 3); //3 3 2 1vector<int> a(2, 0);name.insert(it, a.begin(), a.begin() + 1); //0 0 3 3 2 1
2. 刪除
- void pop_back():刪除vector中最后一個元素
- void clear():清空vector中所有元素
- iterator erase(iterator it):刪除vector中迭代器 it 指向的元素
- iterator erase(iterator first, iterator last):刪除vector中 [first,last) 范圍內的元素
//0 0 3 3 2 1name.pop_back(); //0 0 3 3 2vector<int>::iterator it = name.begin();name.erase(it); //0 3 3 2name.erase(it, it + 1); //3 2name.clear();
3. 遍歷
- iterator begin():返回向量頭指針,指向第一個元素
- iterator end():返回向量尾指針,指向向量最后一個元素的下一個位置
- reference at(int pos):返回 pos 位置元素的引用
- reference front():返回首元素的引用
- reference back():返回尾元素的引用
- reverse_iterator rbegin():反向迭代器,指向最后一個元素,即將vector反轉后,返回第一個元素
- reverse_iterator rend():反向迭代器,指向第一個元素之前的位置,即將vector反轉后,返回最后一個元素
4. 判斷
- bool empty() const:判斷向量是否為空,若為空,則向量中無元素
if(name.empty()) return false;
5. 大小
- int size() const:返回向量中元素的個數
int len = name.size();
6. 通過copy函數賦值
vector<int> a(5,1);int a1[5] = {2,2,2,2,2};vector<int> b(10);//將a中元素全部拷貝到b開始的位置中,注意拷貝的區間為a.begin() ~ a.end()的左閉右開的區間copy(a.begin(), a.end(), b.begin());//拷貝區間也可以是數組地址構成的區間copy(a1, a1+5, b.begin() + 5);
五. vector排序
1. 從小到大(升序)
sort排序默認升序,頭文件:#include <algorithm>
int a[] = {8,6,2,9,3,5,4,1,7,10};vector<int> arr(a, a+5);sort(arr.begin(),arr.end()); //升序
2. 從大到小(降序)
- (1)
greater<int>()
sort默認排序從小到大,使用greater<int>()
int a[] = {8,6,2,9,3,5,4,1,7,10};vector<int> arr(a, a+5);sort(arr.begin(),arr.end(),greater<int>()); //降序
- (2)自定義函數 bool cmp(int x, int y);
bool cmp_max(int x,int y){return x > y;
}int main() {int a[] = {8,6,2,9,3,5,4,1,7,10};vector<int> arr(a, a+5);sort(arr.begin(), arr.end(), cmp_max); for(int i = 0; i < arr.size(); i++){printf("%d ", arr[i]);} return 0 ;}
- (3)使用sort排序后,再使用reverse() ,reverse()將元素倒置
sort(arr.begin(),arr.end()); //升序排列reverse(arr.begin(),arr.end()); //將數組倒置
- (4)使用反向迭代器 rbegin() 和 rend()
// sorts arr in "normal" ordersort(arr.begin(), arr.end());// sorts in reverse: puts smallest element at the end of arrsort(arr.rbegin(), arr.rend());
關于反向迭代器,詳見這篇博客:c++ vector begin(),end(),rbegin(),rend()問題 (C++ primer (中文版第四版) 第273頁)
3. 對結構體vector使用sort排序
當vector中的數據類型為自定義結構體類型時(元素大于等于2),想以其中某一個元素進行正序或逆序排序,則不能直接使用sort函數,通過自定義比較函數 cmp 實現排序。
#include <bits/stdc++.h>
using namespace std;struct Point2{int x;int y;
};
bool GreaterSort (Point2 a,Point2 b) { return (a.x > b.x); }
bool LessSort (Point2 a,Point2 b) { return (a.x < b.x); }
int main(){vector<Point2> aaa;Point2 temp;temp.x=1;temp.y=1;aaa.push_back(temp);temp.x=2;temp.y=2;aaa.push_back(temp); temp.x=3;temp.y=3;aaa.push_back(temp);//降序排列sort(aaa.begin(),aaa.end(), GreaterSort);cout<<"Greater Sort:"<<endl;for (int i =0;i<aaa.size();i++){cout<<aaa[i].x<<" "<<aaa[i].y<<endl;}//升序排列sort(aaa.begin(),aaa.end(),LessSort);cout<<"Less Sort:"<<endl;for (int i =0;i<aaa.size();i++){cout<<aaa[i].x<<" "<<aaa[i].y<<endl;}return 0;
}
運行結果:
Greater Sort:
3 3
2 2
1 1
Less Sort:
1 1
2 2
3 3