一、概述
vector(向量): 是一種序列式容器,事實上和數組差不多,但它比數組更優越。一般來說數組不能動態拓展,因此在程序運行的時候不是浪費內存,就是造成越界。而vector正好彌補了這個缺陷,它的特征是相當於可分配拓展的數組(動態數組),它的隨機訪問快,在中間插入和刪除慢,但在末端插入和刪除快。
二、定義及初始化
使用之前必須加相應容器的頭文件:
#include <vector> // vector屬於std命名域的,因此需要通過命名限定,例如using std::vector;
定義的實現代碼如下:
vector<int> a; // 定義一個int類型的向量a
vector<int> a(10); // 定義一個int類型的向量a,並設置初始大小為10
vector<int> a(10, 1); // 定義一個int類型的向量a,並設置初始大小為10且初始值都為1
vector<int> b(a); // 定義並用向量a初始化向量b
vector<int> b(a.begin(), a.begin()+3); // 將a向量中從第0個到第2個(共3個)作為向量b的初始值
除此之外,還可以直接使用數組來初始化向量:
int n[] = {1, 2, 3, 4, 5} ;
// 將數組n的前5個元素作為向量a的初值
// 說明:當然不包括arr[4]元素,末尾指針都是指結束元素的下一個元素,
// 這個主要是為了和vec.end()指針統一。
vector<int> a(n, n+5) ;
vector<int> a(&n[1], &n[4]) ; // 將n[1]、n[2]、n[3]作為向量a的初值
三、基本操作函數
3.1 容量函數
- 容器大小:
vec.size(); - 容器容量:
vec.capacity();// 指在發生 realloc 前能允許的最大元素數,即預分配的內存空間,與 size() 不同 - 容器最大容量:
vec.max_size(); - 更改容器大小:
vec.resize(); - 容器判空:
vec.empty();
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> vec;
for (int i = 0; i<6; i++)
{
vec.push_back(i);
}
cout << vec.size() << endl; // 輸出:6
cout << vec.capacity() << endl; // 輸出:6
cout << vec.max_size() << endl; // 輸出:1073741823
vec.resize(0);
cout << vec.size() << endl; // 輸出:0
if (vec.empty())
cout << "元素為空" << endl; // 輸出:元素為空
return 0;
}
注意:vec.resize(10),會分配 10 個 0 給vec,相當於 push_back(0) 10 次。
3.2 添加函數
- 末尾添加元素:
vec.push_back(const T& x); - 任意位置插入一個元素:
vec.insert(iterator it, const T& x); - 任意位置插入 n 個相同元素:
vec.insert(iterator it, int n, const T& x); - 插入另一個向量的 [forst,last] 間的數據:
vec.insert(iterator it, iterator first, iterator last);
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> vec;
// 末尾添加元素
vec.push_back(5);
// 任意位置插入一個元素
vector<int>::iterator it = vec.begin();
vec.insert(it, 2);
// 任意位置插入n個相同元素
it = vec.begin();
vec.insert(it, 3, 9);
// 插入另一個向量的[forst,last]間的數據
vector<int> vec2(5, 8);
it = vec.begin();
vec.insert(it, vec2.end() - 1, vec2.end());
// 遍歷顯示
for (it = vec.begin(); it != vec.end(); it++)
cout << *it << " "; // 輸出:8 9 9 9 2 5
cout << endl;
return 0;
}
3.3 刪除函數
- 末尾刪除元素:
vec.pop_back(); - 任意位置刪除一個元素:
vec.erase(iterator it); - 刪除 [first,last] 之間的元素:
vec.erase(iterator first, iterator last); - 清空所有元素:
vec.clear();
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> vec;
for (int i = 0; i < 8; i++)
vec.push_back(i);
// 末尾刪除元素
vec.pop_back();
// 任意位置刪除一個元素
vector<int>::iterator it = vec.begin();
vec.erase(it);
// 刪除[first,last]之間的元素
vec.erase(vec.begin(), vec.begin() + 1);
for (it = vec.begin(); it != vec.end(); it++)
cout << *it << " ";
cout << endl;
// 清空所有元素
vec.clear();
// 遍歷顯示
for (it = vec.begin(); it != vec.end(); it++)
cout << *it << " "; // 輸出:2 3 4 5 6
cout << endl;
return 0;
}
3.4 訪問函數
- 下標訪問:
vec[1];// 並不會檢查是否越界 - at 方法訪問:
vec.at(1);// 以上兩者的區別就是 at 會檢查是否越界,是則拋出 out of range 異常 - 訪問第一個元素:
vec.front(); - 訪問最后一個元素:
vec.back(); - 返回一個指針:
int* p = vec.data();// 可行的原因在於 vector 在內存中就是一個連續存儲的數組,所以可以返回一個指針指向這個數組。這是是 C++11 的特性。
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> vec;
for (int i = 0; i < 6; i++)
vec.push_back(i);
// 下標訪問
cout << vec[0] << endl; // 輸出:0
// at方法訪問
cout << vec.at(0) << endl; // 輸出:0
// 訪問第一個元素
cout << vec.front() << endl; // 輸出:0
// 訪問最后一個元素
cout << vec.back() << endl; // 輸出:5
// 返回一個指針
int *p = vec.data();
cout << *p <<endl; // 輸出:0
return 0;
}
3.5 其他函數
- 多個元素賦值:
vec.assign(int nSize, const T& x);// 類似於初始化時用數組進行賦值 - 交換兩個同類型容器的元素:
swap(vector&);
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
// 多個元素賦值
vector<int> vec;
vec.assign(3, 1);
vector<int> vec2;
vec2.assign(3, 2);
// 交換兩個容器的元素
vec.swap(vec2);
// 遍歷顯示
cout << "vec: ";
for (int i = 0; i < vec.size(); i++)
cout << vec[i] << " "; // 輸出:2 2 2
cout << endl;
// 遍歷顯示
cout << "vec2: ";
for (int i = 0; i < vec2.size(); i++)
cout << vec2[i] << " "; // 輸出:1 1 1
cout << endl;
return 0;
}
四、迭代器與算法
1. 迭代器
- 開始指針:
vec.begin(); - 末尾指針:
vec.end();// 指向最后一個元素的下一個位置 - 指向常量的開始指針:
vec.cbegin();// 意思就是不能通過這個指針來修改所指的內容,但還是可以通過其他方式修改的,而且指針也是可以移動的。 - 指向常量的末尾指針:
vec.cend();
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
cout << *(vec.begin()) << endl; // 輸出:1
cout << *(--vec.end()) << endl; // 輸出:3
cout << *(vec.cbegin()) << endl; // 輸出:1
cout << *(--vec.cend()) << endl; // 輸出:3
cout << *(vec.rbegin()) << endl; // 輸出:3
cout << *(--vec.rend()) << endl; // 輸出:1
cout << endl;
return 0;
}
2. 算法
- 遍歷元素
vector<int>::iterator it;
for (it = vec.begin(); it != vec.end(); it++)
cout << *it << endl;
// 或者
for (int i = 0; i < vec.size(); i++) {
cout << vec.at(i) << endl;
}
- 元素翻轉
#include <algorithm>
reverse(vec.begin(), vec.end());
- 元素排序
#include <algorithm>
sort(vec.begin(), vec.end()); // 采用的是從小到大的排序
// 如果想從大到小排序,可以采用先排序后反轉的方式,也可以采用下面方法:
// 自定義從大到小的比較器,用來改變排序方式
bool Comp(const int& a, const int& b)
{
return a > b;
}
sort(vec.begin(), vec.end(), Comp);
參考:
[清水汪汪-博客園博客](https:// www.cnblogs.com/zhonghuasong/p/5975979.html)
