1. 程式人生 > >[C++ STL] vector使用詳解

[C++ STL] vector使用詳解

一、vector介紹:

deque(雙端佇列)是一個動態陣列,可以向兩端發展,因此不論在尾部或頭部安插元素都十分迅速。 在中間部分安插元素則比較費時,因為必須移動其它元素。


二、用法

1、標頭檔案

#include <deque>
//deque屬於std命名域的,因此需要通過命名限定,例如using std::deque;

2、定義及初始化

deque<int> a; //定義一個int型別的向量a
deque<int> a(10); //定義一個int型別的向量a,並設定初始大小為10
deque<int> a(10, 1); //定義一個int型別的向量a,並設定初始大小為10且初始值都為1
deque<int> b(a); //定義並用向量a初始化向量b
deque<int> b(a.begin(), a.begin()+3); //將a向量中從第0個到第2個(共3個)作為向量b的初始值

除此之外,還可以直接使用陣列來初始化向量:

int n[] = {1, 2, 3, 4, 5} ;
vector<int> a(n, n+5) ;              //將陣列n的前5個元素作為向量a的初值
//說明:當然不包括arr[4]元素,末尾指標都是指結束元素的下一個元素,
//這個主要是為了和vec.end()指標統一。
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();
  • 減少向量大小到滿足元素所佔儲存空間的大小: vec.shrink_to_fit();
#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.size() << endl;
    cout << "元素容量: " << vec.capacity() << endl;
    cout << "元素最大容量: " << vec.max_size() << endl;
    vec.resize(0); //更改元素大小
    cout << "元素大小: " << vec.size() << endl;
    if (vec.empty())
        cout << "元素為空" << endl;

    return 0;
}

/*
輸出結果:
元素大小: 6
元素容量: 6
元素最大容量: 1073741823
元素大小: 0
元素為空
*/

 

(2) 修改

  • 多個元素賦值: vec.assign(); //類似於初始化時用陣列進行賦值
  • 末尾新增元素: vec.push_back();
  • 末尾刪除元素: vec.pop_back();
  • 任意位置插入元素: vec.insert();
  • 任意位置刪除元素: vec.erase();
  • 交換兩個向量的元素: swap();
  • 清空向量元素: vec.clear();
#include "stdafx.h"
#include <iostream>
#include <vector>

using namespace std;

int main(int argc, char* argv[])
{
    vector<int> vec;

    //多個元素賦值
    vec.assign(3, 1);
    //末尾新增元素
    vec.push_back(4);
    vec.push_back(5);
    //末尾刪除元素
    vec.pop_back();
    //任意位置插入元素
    vector<int>::iterator it = vec.begin();
    vec.insert(++it, 2);
    /*** 任意位置刪除元素 ***/
    //刪除單個元素 erase(it)
    vec.erase(it);
    //刪除一個區間[first, last)的元素erase(first, last) //first與last都是迭代器
    vec.erase(vec.end() - 1, vec.end()); //刪除最後一個元素
    //交換兩個向量的元素
    vector<int> vec2(3, 2);
    swap(vec, vec2);

    //display vec
    cout << "vec: ";
    for (it = vec.begin(); it != vec.end(); it++)
        cout << *it << " ";
    cout << endl;
    //display vec2
    cout << "vec2: ";
    for (int i = 0; i<vec2.size(); i++)
        cout << vec2[i] << " ";
    cout << endl;

    //清空向量元素
    vec.clear();
    cout << "clear,vec: ";
    for (it = vec.begin(); it != vec.end(); it++)
        cout << *it << " ";
    cout << endl;

    return 0;
}

/*
vec: 2 2 2
vec2: 1 1 1
clear,vec:
*/

 

(3) 迭代器

  • 開始指標:vec.begin();
  • 末尾指標:vec.end(); //指向最後一個元素的下一個位置
  • 指向常量的開始指標: vec.cbegin(); //意思就是不能通過這個指標來修改所指的內容,但還是可以通過其他方式修改的,而且指標也是可以移動的。
  • 指向常量的末尾指標: vec.cend();
#include "stdafx.h"
#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()): " <<*(vec.begin()) <<endl;
    cout << "*(vec.end()): " << *(--vec.end()) << endl;
    cout << "*(vec.cbegin()): " << *(vec.cbegin()) <<endl;
    cout << "*(vec.cend()): " << *(--vec.cend()) <<endl;
    cout << endl;

    return 0;
}

/*
*(vec.begin()): 1
*(vec.end()): 3
*(vec.cbegin()): 1
*(vec.cend()): 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;
    //at方法訪問
    cout << "at方法訪問: " << vec.at(0) << endl;
    //訪問第一個元素
    cout << "訪問第一個元素: " << vec.front() << endl;
    //訪問最後一個元素
    cout << "訪問最後一個元素: " << vec.back() << endl;
    //返回一個指標
    int *p = vec.data();
    cout << "指標指向元素: " << *p <<endl;

    return 0;
}

/*
下標訪問: 0
at方法訪問: 0
訪問第一個元素: 0
訪問最後一個元素: 5
指標指向元素: 0
*/

 

(5) 演算法

  • 遍歷元素
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);

參考文獻:

部落格園vector部落格