deque

N1ce2cu發表於2024-08-20

deque

deque<T>,一個定義在 deque 標頭檔案中的容器模板,可以生成包含 T 型別元素的容器,它以雙端佇列的形式組織元素。可以在容器的頭部和尾部高效地新增或刪除物件,這是它相對於 vector 容器的優勢。

建立

#include <algorithm>
#include <string>
#include <deque>

using namespace std;

int main() {
    // 預設的建構函式生成 deque 容器,容器中沒有任何元素,因此新增第一個元素,就會導致記憶體的分配
    deque<int> data1;
    // 生成給定元素個數的 deque 容器,每個元素儲存的都是這種元素型別的預設值
    deque<int> data2(10);
    // 用初始化列表來生成 deque 容器
    deque<string> words{"one", "none", "some", "all", "none", "most", "many"};

    // 生成現有容器的副本
    deque<string> words_copy{words};
    // 由兩個迭代器標識的一段元素來初始化它,作為初始值的一段元素,可以來自任何種類的容器,不需要一定是 deque
    // 這個容器有 5 個元素,它們和 words 容器的前 5 個元素相等
    deque<string> words_part{begin(words), begin(words) + 5};
}

訪問

deque 容器中的元素是序列,但是內部的儲存方式和 vector 不同。它組織元素的方式導致容器的大小總是和容量相等。因此沒有定義成員函式 capacity(),deque 只有成員函式 size(),它以成員型別 size_type 的無符號整型來返回當前元素個數。

可以用下標運算子來訪問元素,但是索引並沒有進行邊界檢查。為了用進行邊界檢查的索引來訪問元素,可以選擇使用成員函式 at(),這和 vector 相同。

deque 成員函式 front()back() 的用法也和 vector 相同,然而,deque 卻沒有成員函式 data(),因為元素並沒有被存放在陣列中。deque 容器和 vector 一樣,有三種不同過載版本的 resize() 函式,它們的操作基本相同。

新增和刪除

deque 和 vector 都有成員函式 push_back() 和 pop_back(),它們在序列尾部新增或刪除元素的方式相同。deque 也有成員函式 push_front() 和 pop_front(),可以在序列頭部執行相似的操作。

除了和 vector —樣都有 emplace_back() 函式外,deque 還有成員函式 emplace_front(),可以在序列的開始位置生成新的元素。和 vector 一樣,也可以使用 emplace() 或 insert() 在 deque 內部新增或移除元素。這個過程相對要慢一些,因為這些操作需要移動現有的元素。

關於 vector 容器的所有 insert() 函式也同樣適用於 deque 容器。在 deque 的任意位置插入一個元素會讓現有的迭代器全部失效,因此需要重新生成它們。deque 的成員函式 erase() 也和 vector 的相同,它的成員函式 clear() 可以移除一些元素。

修改

#include <algorithm>
#include <string>
#include <deque>
#include <iostream>
#include <vector>

using namespace std;

int main() {
    deque<string> words{"one", "two", "three", "four"};
    auto init_list = {string{"seven"}, string{"eight"}, string{"nine"}};

    // 1.用 init_list 中的 string 物件替換掉了 words 中的元素
    /*
     * 這裡不能直接把字元放入初始化列表。
     * 如果這麼做,init_list 的型別會被推導為 initializer_list<const char*>,
     * 然而 assign() 需要的是一個 initializer_list<string> 型別的實參,這樣就無法透過編譯。
     */
    words.assign(init_list);
    // 也可以不單獨定義 init_list,可以在 assign() 的實參中定義初始化列表
    // words.assign({"seven", "eight", "nine"});
    // deque: seven eight nine

    // 2.提供兩個迭代器作為引數
    vector<string> wordSet{"this", "that", "these", "those"};
    words.assign(begin(wordSet) + 1, end(wordSet) - 1);
    // deque: that these

    // 3.用重複的物件來替換容器中的內容
    words.assign(2, "two");
    // deque: two two

    // 為 deque 替換一套新元素
    // otlier_words 會包含和 words 相同的元素,words 則包含初始化列表中的那些元素
    deque<string> other_words;
    other_words = words;
    words = {"seven", "eight", "nine"};
}