- 1. 簡介
- 2. 使用注意
- 3. 基本操作
- 3.1 頭文件
- 3.2 創建vector對象
- 3.3 尾部插入元素 `push_back()`
- 3.4 尾部刪除元素 `pop_back()`
- 3.5 使用下標訪問元素`[]`
- 3.6 使用`at()`方法訪問
- 3.7 使用迭代器訪問元素
- 3.8 插入元素 `insert()`
- 3.9 刪除元素 `erase()`
- 3.10 vectors實際存儲元素個數 `size()`
- 3.11 vectors容量大小 `capacity()`
- 3.12 清空 `clear()`
- 3.13 使用 `reverse()` 將元素翻轉
- 3.14 `swap()` 交換 vector
- 3.15 `sort()` 排序
- 3.16 改變vector的大小 `resize()`
- 3.17 改變vector容量的大小 `reserve()`
- 4.一維數組的使用
- 5.二維數組的使用
- 6. `begin()`與`end()` 、`front()`與`back()`區別
- 7. `resize()` 和 `reserve()`
- 8. Reference
1. 簡介
在c++中,vector是一個十分有用的容器。
作用:它能夠像容器一樣存放各種類型的對象,簡單地說,vector是一個能夠存放任意類型的動態數組,能夠增加和壓縮數據。vector在C++標準模板庫中的部分內容,它是一個多功能的,能夠操作多種數據結構和算法的模板類和函數庫。
2. 使用注意
1、如果你要表示的向量長度較長(需要爲向量內部保存很多數),容易導致內存泄漏,而且效率會很低;
2、Vector作爲函數的參數或者返回值時,需要注意它的寫法:
double Distance(vector<int>&a, vector<int>&b) // 其中的 “&” 絕對不能少!!!
3. 基本操作
3.1 頭文件
#include <vector>
3.2 創建vector對象
vector<int> v1; // vec是一個空int類型的vector對象,執行默認初始化
vector<int> v2(v1); // v2包含有v1所有元素的副本
vector<int> v2 = v1; // 等價於上面這條語句
vector<int> v3(n, val); // v3包含了n個int類型值爲val的元素
vector<int> v4(n); // v4包含了n個重複地執行了值初始化的對象
vector<int> v5 {1, 2, 3}// v5是一個含有3個int類型的vector,其中每個元素被賦予相應的初始值
vector<int> v5 = {1, 2, 3}// 與上面語句等價
3.3 尾部插入元素 push_back()
vec.push_back(1);
3.4 尾部刪除元素 pop_back()
vec.pop_back();
3.5 使用下標訪問元素[]
cout << vec[0] << endl; // 記住下標是從0開始的。
3.6 使用at()
方法訪問
cout << vec.at(0) << endl; // 使用at方法訪問,如果vector爲空,會拋出異常,下標法則不會(效率更高)
3.7 使用迭代器訪問元素
vector<int>::iterator it;
for(it=vec.begin(); it!=vec.end(); it++)
cout << *it << endl;
3.8 插入元素 insert()
vec.insert(vec.begin()+i, a); // 在第i+1個元素前面插入a;
3.9 刪除元素 erase()
vec.erase(vec.begin()+2); // 刪除第3個元素
vec.erase(vec.begin()+i, vec.end()+j); // 刪除區間[i,j-1];區間從0開始
注意:
size()
表示vector實際存儲元素個數,capacity()
表示vector容量大小,即分配的存儲空間的大小。舉例記憶:一間房間有100個座位(capacity),當前只坐了40人(size)。
3.10 vectors實際存儲元素個數 size()
vec.size();
3.11 vectors容量大小 capacity()
vec.capacity();
3.12 清空 clear()
vec.clear();
3.13 使用 reverse()
將元素翻轉
#include <algorithm>
reverse(vec.begin(), vec.end()); // 將元素翻轉,即逆序排列
// (在vector中,如果一個函數中需要兩個迭代器,一般後一個都不包含) ? 沒看懂
3.14 swap()
交換 vector
vector<int> a(3, 100); // three ints with a value of 100
vector<int> b(5, 100); // five ints with a value of 200
a.swap(b); // swap two vectors
3.15 sort()
排序
#include <algorithm>
sort(vec.begin(),vec.end()); // 默認是按升序排列,即從小到大
// 可以通過重寫排序比較函數按照降序比較,如下定義排序比較函數:
bool Comp(const int &a,const int &b) {
return a>b;
}
// 調用時:sort(vec.begin(),vec.end(),Comp); 這樣就降序排序。
注意:vector提供了兩個方法
resize()
和reserve()
分別對size()
和capacity()
進行操作.
Reference:C++基礎篇 – vector的resize函數和reserve函數
3.16 改變vector的大小 resize()
vector<int> vec;
vec.resize(5); // 將空vector數組大小更改爲5
vec.resize(8, 35); // 將vec數組大小更改爲8,並將新增加的元素,初始化爲指定值35
for (int i=0;i<vec.size();i++)
std::cout << ' ' << vec[i];
// 結果爲:0 0 0 0 0 35 35 35
1、resize方法被用來改變vector的大小,即vector中元素的數量,我們可以說,resize方法改變了容器的大小,且創建了容器中的對象;
2、如果resize中所指定的n小於vector中當前的元素數量,則會刪除vector中多於n的元素,使vector得大小變爲n;
3、如果所指定的n大於vector中當前的元素數量,則會在vector當前的尾部插入適量的元素,使得vector的大小變爲n,在這裏,如果爲resize方法指定了第二個參數,則會把後插入的元素值初始化爲該指定值,如果沒有爲resize指定第二個參數,則會把新插入的元素初始化爲默認的初始值;
4、如果resize所指定的n不僅大於vector中當前的元素數量,還大於vector當前的capacity容量值時,則會自動爲vector重新分配存儲空間;
3.17 改變vector容量的大小 reserve()
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vect;
vect.reserve(5);
vect.push_back(1);
vect.push_back(2);
vect.push_back(3);
vect.push_back(4);
cout << vect.size() << endl;
cout << vect.capacity() << endl;
vect.push_back(5);
vect.push_back(6); // 插入兩個元素,此時vect的大小大於之前分配的容量5
cout << "size1 = " << vect.size() << endl;
cout << "capacity1 = " << vect.capacity() << endl;
vect.push_back(7);
vect.push_back(8); // 在插入兩個元素,和上面的結果進行對比,會有意外收穫
cout << "size1_1 = " << vect.size() << endl;
cout << "capacity1_1 = " << vect.capacity() << endl;
vect.reserve(3); // 當程序執行到此處時,vect的容量大小一定是大於3的
cout << "size2 = " << vect.size() << endl;
cout << "capacity2 = " << vect.capacity() << endl;
vect.reserve(12);
cout << "size3 = " << vect.size() << endl;
cout << "capacity3 = " << vect.capacity() << endl;
return 0;
}
/**輸出結果
4
5
size1 = 6
capacity1 = 10
size1_1 = 8
capacity1_1 = 10
size2 = 8
capacity2 = 10
size3 = 8
capacity3 = 12
*/
1、reserve方法被用來重新分配vector的容量大小;
2、只有當所申請的容量大小n大於vector的當前容量時,纔會重新爲vector分配存儲空間;
3、reserve方法對於vector的大小(即size)沒有任何影響;
4.一維數組的使用
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
int main() {
vector<int> a; // 創建一個int類型的vector數組 a
a.push_back(1);
a.push_back(2); // 把1和2壓入vector
cout << a[0] << endl; // 下標法訪問數組,輸出爲1
cout << a.at(1) << endl; // at法訪問數組,輸出爲2
// at和下標法的區別是,如果vector爲空,調at會拋出異常,而operator[]索引的行爲爲定義
// 使用迭代器訪問數組元素
for(vector<int>::iterator it = a.begin(); it != a.end(); it++)
cout << *it << endl;
}
5.二維數組的使用
這裏簡單敘述一下C++ 構建二維動態數組
int **p;
p = new int*[10]; // 注意,int*[10]表示一個有10個元素的指針數組
for (int i = 0; i < 10; ++i)
p[i] = new int[5];
1. 初始化
(1)利用Vector的push_back函數
vector<vector<int> > vec;
vector<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
vector<int> b;
b.push_back(4);
b.push_back(5);
b.push_back(6);
vec.push_back(a);
vec.push_back(b);
(2)先定義好二維數組結構,再直接賦值
// 得到一個5行3列的數組
// 由vector實現的二維數組,可以通過resize()的形式改變行、列值
int i, j;
vector<vector<int> > array(5);
for (i = 0; i < array.size(); i++)
array[i].resize(3);
for(i = 0; i < array.size(); i++)
for (j = 0; j < array[0].size();j++)
array[i][j] = (i+1)*(j+1);
2. 遍歷
(1)利用迭代器
void reverse_with_iterator(vector<vector<int>> vec) {
if (vec.empty()) {
cout << "The vector is empty!" << endl;
return;
}
vector<int>::iterator it;
vector<vector<int>>::iterator iter;
vector<int> vec_tmp;
cout << "Use iterator : " << endl;
for(iter = vec.begin(); iter != vec.end(); iter++) {
vec_tmp = *iter;
for(it = vec_tmp.begin(); it != vec_tmp.end(); it++)
cout << *it << " ";
cout << endl;
}
}
(2)得到行、列大小,利用下標進行遍歷
void reverse_with_index(vector<vector<int>> vec) {
if (vec.empty()) {
cout << "The vector is empty!" << endl;
return;
}
int i,j;
cout << "Use index : " << endl;
for (i = 0; i < vec.size(); i++) { // 注意,當內層每個vector沒有存滿時,這個樣會出錯
for(j = 0; j < vec[0].size(); j++)
cout << vec[i][j] << " ";
cout << endl;
}
}
注意: vector的元素不僅僅可以是int,double,string,還可以是結構體,但是要注意:結構體要定義爲全局的,否則會出錯。
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
typedef struct rect {
int id;
int length;
int width;
// 對於向量元素是結構體的,可在結構體內部定義比較函數,下面按照id,length,width升序排序。
bool operator< (const rect &a) const {
if(id!=a.id)
return id<a.id;
else {
if(length!=a.length)
return length<a.length;
else
return width<a.width;
}
}
}Rect;
int main() {
vector<Rect> vec;
Rect rect;
rect.id=1;
rect.length=2;
rect.width=3;
vec.push_back(rect);
vector<Rect>::iterator it=vec.begin();
cout<<(*it).id<<' '<<(*it).length<<' '<<(*it).width<<endl;
return 0;
}
6. begin()
與end()
、front()
與back()
區別
函數原型:
iterator begin();
const_iterator begin();
功能:返回一個當前vector容器中起始元素的迭代器。
函數原型:
iterator end();
const_iterator end();
功能:返回一個當前vector容器中末尾元素的迭代器。
函數原型:
reference front();
const_reference front();
功能: 返回當前vector容器中起始元素的引用。
函數原型:
reference back();
const_reference back();
功能: 返回當前vector容器中末尾元素的引用。
例題
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<char> v1;
vector<char>::iterator iter1;
vector<char>::iterator iter2;
v1.push_back('m');
v1.push_back('n');
v1.push_back('o');
v1.push_back('p');
cout << "v1.front() = " << v1.front() << endl;
cout << "v1.back() = " << v1.back() << endl;
iter1 = v1.begin();
cout << *iter1 << endl;
iter2 = v1.end()-1; // 注意v1.end()指向的是最後一個元素的下一個位置,所以訪問最後一個元素
// 的正確操作爲:v1.end() - 1;
cout << *iter2 << endl;
return 0;
}
/*
最後輸出結果:
v1.front() = m
v1.back() = p
m
p
*/