C++ STL 之 deque

本節(jié)我們將介紹 STL 中的 deque 容器使用。



deque<T>,是一個(gè)定義在 deque 頭文件中的容器模板,可以生成包含 T 類型元素的容器,它以雙端隊(duì)列的形式組織元素,因此可以在容器的頭部和尾部高效地添加或刪除對(duì)象,它可以處理先進(jìn)先出類型的事務(wù),類似于棧這種數(shù)據(jù)結(jié)構(gòu),它的使用和 vector 相似,但 vector 只能在容器末尾處增加和刪除元素。

deque 容器的初始化

初始化方式:
1.使用默認(rèn)的構(gòu)造函數(shù)生成 deque 容器,容器中沒(méi)有任何元素,大小為0,當(dāng)添加第一個(gè)元素,就就會(huì)有內(nèi)存的分配。

deque<string> data;

2.和 vector 容器在本質(zhì)上相同類似,可以生成給定元素個(gè)數(shù)的 deque 容器。

deque<string> data(7);

或者

deque<string> data(7,"seven");

3.可以用初始化列表來(lái)生成 deque 容器。

deque<string> data {"one","null","three","four","null","six","seven"};

4.也可以用由兩個(gè)迭代器標(biāo)識(shí)的一段元素來(lái)初始化它。

deque<string> data {"one","null","three","four","null","six","seven"};
deque<string> data_ {data};

或者

deque<string> data {"one","null","three","four","null","six","seven"};
deque<string> data_ {begin(data)+2,end(data)-2};

接下來(lái),我們匯總下 deque 容器的初始化。
示例如下:

#include <bits/stdc++.h>
using namespace std;

int main(){
    deque<string> data_1;
    deque<string> data_2(7);
    deque<string> data_3(7,"null");
    deque<string> data_4 {"one","null","three","four","null","six","seven"};
    //全部復(fù)制
    deque<string> data_5{data_4};
    auto begin_iter = begin(data_4);
    deque<string>::iterator end_iter = end(data_4);
    begin_iter += 2;
    end_iter -= 2;
    //部分復(fù)制
    deque<string> data_6{begin_iter,end_iter};
    cout<<"data_1: "<<data_1.size()<<endl;
    for(auto d : data_1){
        cout<<d<<" ";
    }
    cout<<endl;
    cout<<"data_2: "<<data_2.size()<<endl;
    for(auto d : data_2){
        cout<<d<<" ";
    }
    cout<<endl;
    cout<<"data_3: "<<data_3.size()<<endl;
    for(auto d : data_3){
        cout<<d<<" ";
    }
    cout<<endl;
    cout<<"data_4: "<<data_4.size()<<endl;
    for(auto d : data_4){
        cout<<d<<" ";
    }
    cout<<endl;
    cout<<"data_5: "<<data_5.size()<<endl;
    for(auto d : data_5){
        cout<<d<<" ";
    }
    cout<<endl;
    cout<<"data_6: "<<data_6.size()<<endl;
    for(auto d : data_6){
        cout<<d<<" ";
    }
    cout<<endl;
    return 0;
}

結(jié)果如下:

image.png

deque 容器的訪問(wèn)

和 vector 類似,我們可以使用下標(biāo)索引和 at() 方法進(jìn)行訪問(wèn)容器內(nèi)的元素,使用 size() 方法得到容器的大小。
同時(shí) at() 方法比索引方法安全,因?yàn)樗黾恿诉吔鐧z查,越界時(shí)會(huì)拋出 out_of_range 異常。
示例如下:

#include <bits/stdc++.h>
using namespace std;

int main(){
    deque<string> data {"one","null","three","four","null","six","seven"};
    cout<<"data: "<<data.size()<<endl;
    for(int i=0;i<data.size();i++){
        cout<<data[i]<<" ";
    }
    cout<<endl;
    cout<<"data: "<<data.size()<<endl;
    //推薦使用 at() 方法
    for(int i=0;i<data.size();i++){
        cout<<data.at(i)<<" ";
    }
    cout<<endl;
    return 0;
}

結(jié)果如下:

image.png

deque 成員函數(shù) front() 和 back() 的用法也和 vector 相同。參考之前 vector 章節(jié)內(nèi)容即可。

deque 容器添加和刪除元素

我們知道,在 vector 中,有 push_back() 和 pop_back() 方法,可以在 vector 容器的尾部增加和刪除元素。
deque 容器不僅能在容器尾部增加和刪除元素,在頭部也可以增加和刪除元素。

deque<string> data {"one","two","three","four"};
//在頭部增加一個(gè)元素
data.push_front("zeros");
//刪除頭部的元素
data.pop_front();
//在尾部增加一個(gè)元素
data.push_back("five");
//刪除尾部的元素
data.pop_back();

除了和 vector —樣都有 emplace_back() 函數(shù)外,deque 還有成員函數(shù) emplace_front(),可以在序列的開始位置生成新的元素。

deque<string> data {"one","two","three","four"};
string word = "zeros five";
//從word中截取,從6開始的4個(gè)字符,在尾部加入
data.emplace_back(word,6,4);
//從word中截取,從0開始的5個(gè)字符,在頭部加入
data.emplace_front(word,0,5);

和 vector 一樣,我們也可以使用 emplace() 或 insert() 在 deque 內(nèi)部添加或移除元素。
但這個(gè)過(guò)程相對(duì)要慢一些,因?yàn)檫@些操作需要移動(dòng)容器內(nèi)現(xiàn)有元素。
emplace():

deque<string> data {"one","two","three","four"};
auto iter = end(data);
//使用 emplace() 容器尾部添加一個(gè) "AAA"
data.emplace(iter,3,'A');
iter = end(data);
iter--;
//在 data 的倒數(shù)第一個(gè)元素前加上一個(gè) "AAAA"
data.emplace(iter,4,'A');

insert():

deque<string> data {"one","two","three","four"};
deque<string> data_add {"six","seven"};
auto iter = end(data);
string goal = "five";
// 在容器后面增加一個(gè) "five"
data.insert(iter,goal);
iter = begin(data);
iter++;
goal = "one_two";
//在容器第 0 個(gè)元素后增加一個(gè) "one_two"
data.insert(iter,goal);
auto begin_iter = begin(data_add);
auto end_iter = end(data_add);
//插入 data_add 的一部分,在 data 尾部插入
iter = end(data);
data.insert(iter,begin_iter,end_iter);

之前系列文章中關(guān)于 vector 容器的 insert() 函數(shù)的使用也適用于 deque 容器。在 deque 的任意位置插入一個(gè)元素會(huì)讓現(xiàn)有的迭代器全部失效,因此需要重新生成迭代器。
deque 的成員函數(shù)clear() , erase() 也和 vector 的相同。
clear():

deque<string> data {"one","two","three","four"};
//清除 deque 容器內(nèi)的所有元素
data.clear();

erase():

deque<string> data {"null","one","two","three","four","five"};
auto iter = begin(data);
//刪除一個(gè)元素,由一個(gè)迭代器指定位置
data.erase(iter);
//此時(shí)容器內(nèi)的元素為: {"one","two","three","four","five"}
auto begin_iter = begin(data);
auto end_iter = end(data);
//使用兩個(gè)迭代器,用來(lái)指定刪除元素的范圍
begin_iter += 2;
end_iter -= 1;
data.erase(begin_iter,end_iter);

該部分的內(nèi)容和 vector 容器大同小異,更詳細(xì)的可以參考之前關(guān)于 vector 方面的博客。

deque 容器修改元素

deque 的成員函數(shù) assign() 可以替換現(xiàn)有的所有元素,它有三個(gè)重版版本:

1.替換的新內(nèi)容是由初始化列表指定的元素
2.替換的新內(nèi)容是由迭代器指定的一段元素
3.替換的新內(nèi)容是一個(gè)特定對(duì)象的多個(gè)副本
使用初始化列表
deque<string> data {"one","two","three","four","five"};
auto data_ = {string{"null"},string{"nine"},string{"null"}};
data.assign(data_);

注意,此句

auto data_ = {string{"null"},string{"nine"},string{"null"}};

不能寫成

auto data_ = {"null","nine","null"};

因?yàn)檫@么做,data_ 的類型會(huì)被推導(dǎo)為 initializer_list<const char*>,然而 assign() 需要的是一個(gè) initializer_list<string> 類型的實(shí)參,這樣就無(wú)法通過(guò)編譯。
當(dāng)然,我們可以在 assign() 的實(shí)參中直接定義初始化列表

deque<string> data {"one","two","three","four","five"};
data.assign({"null","nine","null"});

這樣,data 的內(nèi)容

{"one","two","three","four","five"}

將會(huì)被初始化成 data_ 的內(nèi)容

{"null","nine","null"}
由迭代器指定的一段元素
deque<string> data {"one","two","three","four","five"};
deque<string> data_ {"never","hardly ever","sometimes","often","usually","always"};
deque<string>::iterator begin_iter = begin(data_);
auto end_iter = end(data_);
begin_iter++;
end_iter--;
data.assign(begin_iter,end_iter);

此時(shí),data 的內(nèi)容為:

{"hardly ever","sometimes","often","usually"}
一個(gè)特定對(duì)象的多個(gè)副本

assign() 中第一個(gè)參數(shù)指定了替換當(dāng)前容器內(nèi)容的第二個(gè)參數(shù)的個(gè)數(shù)

deque<string> data {"one","two","three","four","five"};
data.assign(5,"null");

此時(shí),data 的內(nèi)容為:

{"null","null","null","null","null"}

最后,我們來(lái)看看容器的賦值操作,只要賦值運(yùn)算的右操作數(shù)必須和左操作數(shù)是相同類型,就可以完成賦值操作。
示例如下:

#include <bits/stdc++.h>
using namespace std;

int main(){
    deque<string> data {"one","two","three","four","five"};
    deque<string> data_;
    data_ = data;
    cout<<"data: "<<data.size()<<endl;
    for(auto d : data){
        cout<<d<<" ";
    }
    cout<<endl;
    cout<<"data_: "<<data_.size()<<endl;
    for(auto d : data_){
        cout<<d<<" ";
    }
    cout<<endl;
    //data 的元素發(fā)生更改
    data = {"hardly ever","sometimes","often","usually"};
    cout<<"data: "<<data.size()<<endl;
    for(auto d : data){
        cout<<d<<" ";
    }
    cout<<endl;
    cout<<"data_: "<<data_.size()<<endl;
    for(auto d : data_){
        cout<<d<<" ";
    }
    cout<<endl;
    return 0;
}

結(jié)果如下:

image.png

至此,deque 的內(nèi)容暫告一段落了,可以看出,deque 的使用和 vector 其實(shí)大同小異,它的特點(diǎn)之一是可以在容器的頭部和尾部增加元素,當(dāng)然由于移動(dòng)元素,時(shí)空代價(jià)會(huì)略有增加。
deque 容器的部分細(xì)節(jié)和 vector 很相似,例如刪除元素后,迭代器的變化,在之前的博客中也有所介紹,這里就不詳細(xì)展開了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • #1.順序容器概述 #2.容器庫(kù)概覽迭代器容器類型成員begin和end成員容器定義和初始化賦值和swap容器大小...
    MrDecoder閱讀 1,279評(píng)論 0 1
  • 順序容器概述 C++標(biāo)準(zhǔn)庫(kù)中的順序容器為程序員提供了控制元素存儲(chǔ)和順序訪問(wèn)元素的能力,包括vector,strin...
    土豆吞噬者閱讀 656評(píng)論 0 0
  • STL部分 1.STL為什么廣泛被使用 C++ STL 之所以得到廣泛的贊譽(yù),也被很多人使用,不只是提供了像vec...
    杰倫哎呦哎呦閱讀 4,465評(píng)論 0 9
  • 容器 在實(shí)際的開發(fā)過(guò)程中, 數(shù)據(jù)結(jié)構(gòu)本身的重要性不會(huì)遜于操作于數(shù)據(jù)結(jié)構(gòu)的算法的重要性, 當(dāng)程序中存在著對(duì)時(shí)間要求很...
    編程小兔崽閱讀 1,181評(píng)論 0 1
  • 本節(jié)我們將介紹 STL 中的 list 容器使用。 list<T> 是定義在 list 頭文件中容器模板,是 T ...
    思想永不平凡閱讀 1,189評(píng)論 0 4

友情鏈接更多精彩內(nèi)容