C++容器的选择和详细操作方法总结(有自己总结)
概述:C++容器是一個(gè)功能十分強(qiáng)大的庫(kù),利用好了這些容器資源,不僅可以提高書(shū)寫(xiě)代碼的速度,更重要的是還可以提高代碼的健壯性。這篇文章旨在盡可能詳細(xì)地說(shuō)明各種容器的優(yōu)缺點(diǎn)和適用場(chǎng)合以及最重要的就是如何使用。
主要內(nèi)容:本文章不會(huì)對(duì)其源代碼進(jìn)行深入分析,而是對(duì)其方法進(jìn)行詳細(xì)介紹,以便于在實(shí)際應(yīng)用中使用。
?
C++容器庫(kù)概述:
C++容器分為順序容器和關(guān)聯(lián)容器兩大類(lèi),其中順序容器主要包括vector,deque,list,forward_list,array,string六種,而關(guān)聯(lián)容器主要包括map,set,multimap,multiset,unordered_map,unordered_set,unordered_multimap,unordered_multiset八種,此外,針對(duì)于順序容器,標(biāo)準(zhǔn)庫(kù)還定義了三個(gè)適配器,分別是stack,queue,priority_queue。
?
敘述順序:
首先是介紹所有容器共有的屬性和獲取屬性的方法,然后介紹如何使用各種順序容器,然后總結(jié)各種順序容器的適用場(chǎng)合和優(yōu)缺點(diǎn)以及各種操作的對(duì)比,然后介紹各種適配器的使用,然后介紹如何使用各種關(guān)聯(lián)容器,最后總結(jié)各種關(guān)聯(lián)容器的適用場(chǎng)合和優(yōu)缺點(diǎn)以及各種操作的對(duì)比。對(duì)于每一種容器的操作,無(wú)非就是如何定義和初始化一個(gè)容器,然后就是訪問(wèn)方法,再就是如何修改容器。
?
注:本文章使用的容器庫(kù)為c++11標(biāo)準(zhǔn),使用的IDE為 visual studio 2017 。
?
一、順序容器共有屬性
1.共有的類(lèi)型別名:
類(lèi)型別名有7個(gè)可分為5類(lèi);
????第一類(lèi)是容器的迭代器類(lèi)型;
????第二類(lèi)是容器的大小類(lèi)型;
????第三類(lèi)是容器的兩迭代器之間的距離類(lèi)型;
????第四類(lèi)是容器中元素的元素類(lèi)型;
????第五類(lèi)是容器中元素的左值類(lèi)型(就是引用);
具體分別是:
第一類(lèi):iterator和const_iterator????reverse_iterator和const_reverse_iterator(反向迭代器)
第二類(lèi):size_type? (vector,string,deque才支持,list,forward_list,array不支持)
list支持 list_object.size()但是支持 list<elem_type>::size_type
第三類(lèi):difference_type(注意!迭代器運(yùn)算僅僅支持可變長(zhǎng)度線性存儲(chǔ)結(jié)構(gòu),即vector,string,deque;而list,forward_list和array則不支持)
第四類(lèi):value_type
第五類(lèi):reference和const_reference
下表是vector\string\deque\list\forward_list\array對(duì)size()和size_type的支持情況:
代碼示例:(以vector為例)
#include<iostream>
#include<vector>
#include<cstdlib>
?
using namespace std;
?
int main() {
?
?? ?vector<int> ival = { 1,2,3,4,5,6,7,8,9 };
?
?? ?//第一類(lèi)
?? ?cout << "使用普通迭代器遍歷輸出:";
?? ?for (vector<int>::iterator i = ival.begin();i != ival.end();++i) {
?? ??? ?cout << *i << " ";
?? ?}
?? ?cout << endl<<"使用常迭代器遍歷輸出";
?? ?for (vector<int>::const_iterator i = ival.begin();i != ival.end();++i) {//注意!這兒的begin與end獲取的迭代器發(fā)生了類(lèi)型轉(zhuǎn)換
?? ??? ?cout << *i << " ";
?? ?}
?? ?cout << endl;
?
?? ?//第二類(lèi)
?? ?cout << "使用下標(biāo)遍歷輸出:";
?? ?for (vector<int>::size_type i = 0;i < ival.size();++i) {
?? ??? ?cout << ival[i] << " ";
?? ?}
?? ?cout << endl;
?
?? ?//第三類(lèi)
?? ?cout << "使用的迭代器的差來(lái)獲取容器長(zhǎng)度:";
?? ?vector<int>::difference_type length = ival.end() - ival.begin();
?? ?cout << "長(zhǎng)度為" << length << endl;
?
?? ?//第四類(lèi)
?? ?cout << "使用元素類(lèi)型以及范圍for語(yǔ)句來(lái)遍歷容器:";
?? ?for (vector<int>::value_type x : ival) {
?? ??? ?cout << x << " ";
?? ?}
?? ?cout << endl;
?
?? ?//第五類(lèi)
?? ?cout << "使用元素引用來(lái)使原容器中每個(gè)元素的值增大1并輸出:";
?? ?for (vector<int>::reference x : ival) {
?? ??? ?++x;
?? ?}
?? ?for (auto x : ival) {
?? ??? ?cout << x << " ";
?? ?}
?? ?cout << endl;
?? ?cout << "使用元素常引用來(lái)遍歷輸出容器中元素:";
?? ?for (vector<int>::const_reference x:ival) {
?? ??? ?cout << x << " ";
?? ?}
?? ?cout << endl;
?
?
?
?? ?system("pause");
}
運(yùn)行結(jié)果:
2.共有的訪問(wèn)屬性的方法
總共有兩類(lèi):
????第一類(lèi)有三個(gè)分別是獲取容器的元素?cái)?shù)量、獲取容器中可保存元素的最大數(shù)量以及判斷該容器是否為空的方法;
????第二類(lèi)是獲取迭代器的方法,總共有8種方法;
具體分別是:
第一類(lèi):c.size()????c.max_size()????c.empty()
第二類(lèi):c.begin()和c.end()????c.cbegin()和c.cend()????c.rbegin()和c.rend()????c.crbegin()和c.crend()
代碼示例:(以vector為例)
#include<iostream>
#include<vector>
#include<cstdlib>
?
using namespace std;
?
int main() {
?
?? ?vector<int> ival = { 1,2,3,4,5,6,7,8,9 };
?
?? ?//第一類(lèi)
?? ?cout << "使用size()成員函數(shù)來(lái)獲取容器元素?cái)?shù)量:有" << ival.size() << "個(gè)元素" << endl;
?? ?cout << "使用max_size()成員函數(shù)來(lái)獲取容器當(dāng)前最大可存儲(chǔ)元素的數(shù)量:最大可存儲(chǔ)" << ival.max_size() << "個(gè)元素" << endl;
?? ?cout << "使用empty()成員函數(shù)來(lái)判斷容器是否為空:";
?? ?if (ival.empty()) {
?? ??? ?cout << "容器為空" << endl;
?? ?}
?? ?else
?? ?{
?? ??? ?cout << "容器不為空" << endl;
?? ?}
?
?? ?//第二類(lèi)
?? ?cout << "使用begin()與end()使容器中各個(gè)元素的值都擴(kuò)大二倍:現(xiàn)在容器中元素的值為 ";
?? ?for (vector<int>::iterator i = ival.begin();i != ival.end();++i) {
?? ??? ?(*i) *= 2;
?? ?}
?? ?for (auto x : ival) {
?? ??? ?cout << x << " ";
?? ?}
?? ?cout << endl;
?? ?cout << "使用cbegin()與cend()訪問(wèn)容器中的元素:";
?? ?for (vector<int>::const_iterator i = ival.cbegin();i != ival.cend();++i) {
?? ??? ?cout << *i << " ";
?? ?}
?? ?cout << endl;
?
?? ?cout << "使用rbegin()與rend()訪問(wèn)容器中的元素 ";
?? ?for (vector<int>::reverse_iterator i = ival.rbegin();i != ival.rend();++i) {
?? ??? ?cout << *i << " ";
?? ?}
?? ?cout << endl;
?? ?cout << "使用crbegin()與crend()訪問(wèn)容器中的元素:";
?? ?for (vector<int>::const_reverse_iterator i = ival.crbegin();i != ival.crend();++i) {
?? ??? ?cout << *i << " ";
?? ?}
?? ?cout << endl;
?
?? ?system("pause");
}
運(yùn)行結(jié)果:
?
二、順序容器
1.vector
(1)定義和初始化
對(duì)于vector的定義和初始化,有8種方法。可以分為五種場(chǎng)合看待;
????第一種是定義一個(gè)空的容器;
????第二種就是將一個(gè)新的容器定義為某個(gè)舊容器的副本;
????第三種就是使用多個(gè)重復(fù)的值初始化一個(gè)容器;
????第四種就是使用多個(gè)確定的值初始化一個(gè)容器;
????第五種就是使用另一個(gè)容器的迭代器來(lái)初始化一個(gè)新的容器。
????(其中除了第一種和第五種只有一種方法,其他的都有兩種方法。而那兩種方法的唯一區(qū)別就是一個(gè)是直接初始化,一個(gè)是值初始化。)
?
具體分別是:
第一種:vector<T> v1;
第二種:vector<T> v2(v1);????vector<T> v2=v1;
第三種:vector<T> v3(n,val);????vector<T> v3(n);
第四種:vector<T> v5{a,b,c...};????vector<T> v5={a,b,c...};
第五種:vector<T> v6(b,e);
?
代碼示例:
#include<iostream>
#include<vector>
#include<string>
#include<cstdlib>
?
using namespace std;
?
//遍歷輸出一個(gè)int型的vector對(duì)象
void Print(string name,vector<int> &ival) {
?? ?cout << "初始化方法:" << name <<" ?---> ?";
?? ?for (auto x : ival) {
?? ??? ?cout << x << " ";
?? ?}
?? ?cout << endl;
}
?
int main() {
?? ?//第一種
?? ?vector<int> v1;
?? ?v1.push_back(1);//這個(gè)操作是向這個(gè)空容器的后面加一個(gè)數(shù)字1
?
?? ?//第二種
?? ?vector<int> v2(v1);
?? ?vector<int> v3 = v1;
?
?? ?//第三種
?? ?vector<int> v4(10, 2);
?? ?vector<int> v5(10);//這個(gè)初始化方法有一個(gè)局限,就是每個(gè)對(duì)象必須有默認(rèn)的初始值,否則編譯不通過(guò)
?
?? ?//第四種
?? ?vector<int> v6{ 1,2,3,4,5,6 };
?? ?vector<int> v7 = { 1,2,3,4,5,6 };
?
?? ?auto begin = v7.cbegin() + 1, end = v7.cend() - 1;//只訪問(wèn)不改變時(shí)推薦使用const_iterator類(lèi)型的迭代器。
?? ?vector<int> v8(begin,end);
?
?? ?//以下遍歷輸出各種容器來(lái)查看各種容器中的內(nèi)容
?? ?Print("第一種", v1);
?? ?Print("第二種(1)", v2);
?? ?Print("第二種(2)", v3);
?? ?Print("第三種(1)", v4);
?? ?Print("第三種(2)", v5);
?? ?Print("第四種(1)", v6);
?? ?Print("第四種(2)", v7);
?? ?Print("第五種", v8);
?
?? ?system("pause");
}
運(yùn)行結(jié)果:
?
(2)訪問(wèn)容器
對(duì)于vector的訪問(wèn)可以分為四種方法:
????第一種是通過(guò)下標(biāo)進(jìn)行訪問(wèn);
????第二種是通過(guò)迭代器;
????第三種是通過(guò)at()成員函數(shù);
????第四種特殊的是獲取容器首尾元素引用;
具體分別是:
第一種:c[n]
第二種:(*i)????/*i是c的迭代器*/
第三種:c.at(n)
第四種:c.back()/*返回c尾元素引用*/????c.front()/*返回c首元素引用*/
代碼示例:
#include<iostream>
#include<vector>
#include<cstdlib>
?
using namespace std;
?
int main() {
?
?? ?vector<int> ival = { 1,2,3,4,5,6,7,8,9 };
?
?? ?//注意訪問(wèn)元素的時(shí)候一定要保證容器是非空的,否則進(jìn)行訪問(wèn)操作是未定義的。
?? ?//以下代碼使用各種訪問(wèn)方法輸出該容器的第3項(xiàng)元素(獲取的都是該元素的引用)
?? ?//第一種
?? ?cout << "第一種使用下標(biāo)訪問(wèn): ---> 該元素的值為" << ival[2] << endl;
?? ?//第二種
?? ?auto i = ival.cbegin() + 2;
?? ?cout << "第二種使用迭代器訪問(wèn): ---> 該元素的值為" << *i << endl;
?? ?//第三種
?? ?cout << "第三種使用at()成員函數(shù)訪問(wèn): ---> 該元素的值為" << ival.at(2) << endl;
?
?? ?//最后一種方法用于獲取首尾元素的引用(一定要注意是引用)
?? ?//第四種
?? ?cout << "第四種獲取該容器的尾元素的引用: ---> 該元素的值為" << ival.back() << endl;
?? ?cout << "第四種獲取該容器的首元素的引用: ---> 該元素的值為" << ival.front() << endl;
?
?? ?system("pause");
}
運(yùn)行結(jié)果:
?
?
(3)修改容器
修改vector容器的類(lèi)別可以分為三類(lèi):
第一類(lèi)是對(duì)一個(gè)定義好的vector對(duì)象賦值,包括三種情況:
????第一種是將一個(gè)容器值賦一個(gè)初值;
????第二種是交換兩個(gè)容器中的內(nèi)容;
????第三種是使用assign()方法進(jìn)行賦值;(assign的好處是可以跨容器賦值)
第二類(lèi)是向一個(gè)vector容器中添加一個(gè)或多個(gè)新的元素,對(duì)于插入的位置,都是在指定迭代器前面,也包括三種情況:
????第一種是在容器的后面插入單個(gè)元素;
????第二種是在容器任意位置插入單個(gè)元素;
????第三種是在容器任意位置插入多個(gè)元素;
(當(dāng)然,第一種情況完全是第二種情況的一個(gè)特例。不過(guò)使用的比較多就分別列出了)
第三類(lèi)就是從vector容器中刪除一個(gè)或多個(gè)元素也包括三種情況;
????第一種是刪除容器尾后元素;
????第二種是刪除容器中某個(gè)特定的元素;
????第三種是刪除容器中某個(gè)范圍的元素,當(dāng)然也可以是全部;
具體分別是:
第一類(lèi):
情況1:c1=c2;????c={a,b,c,...};
情況2:swap(c1,c2);????c1.swap(c2);
情況3:seq.assign(b,e);????seq.assign(列表(il));????seq.assign(n,t);
第二類(lèi):
情況1:c.push_back(t)和c.emplace_back(args);/*返回void*/
情況2:c.insert(p,t)和c.emplace(p,args);/*返回指向新添加的元素的迭代器*/
情況3:c.insert(p,n,t);????c.insert(p,b,e);????c.insert(p,il);/*插入n個(gè)相同元素,插入其他容器在迭代器b和e范圍中的元素,插入列表il中元素,都返回新添加的元素中第一個(gè)元素的迭代器*/
注:在以上方法中insert與emplace的唯一區(qū)別是前者是拷貝對(duì)象,而后者是構(gòu)造對(duì)象。
第三類(lèi):
情況1:c.pop_back()/*返回void*/
情況2:c.erase(p)/*返回被刪元素之后的元素的迭代器*/
情況3:c.erase(b,e)/*返回一個(gè)指向最后一個(gè)被刪元素之后元素的迭代器*/;????c.clear()/*清空,返回void*/
代碼示例:
#include<iostream>
#include<string>
#include<list>
#include<vector>
?
using namespace std;
?
void Print(string name,vector<int> &x) {
?? ?cout << name<<":";
?? ?for (auto i : x) {
?? ??? ?cout << i << " ";
?? ?}
?? ?cout << endl;
}
?
int main() {
?? ?vector<int> c1{ 1,2,3,4,5,6,7,8,9 };
?? ?Print("c1中元素:", c1);
?? ?vector<int> c2;
?? ?vector<int> c3;
?
?
?? ?cout << "第一類(lèi):" << endl;
?? ?cout << "第一種:" << endl;
?? ?c2 = c1;
?? ?Print("使用\'=\'賦值后c2中元素", c2);
?? ?c3 = { 9,8,7,6,5,4,3,2,1 };
?? ?Print("使用列表賦值后c3中元素", c3);
?? ?cout << endl;
?
?? ?cout << "第二種:" << endl;
?? ?cout << "將c2與c3中的元素交換:" << endl;
?? ?cout << "未交換前:" << endl;
?? ?Print("c2中元素", c2);
?? ?Print("c3中元素", c3);
?? ?cout << "交換后:" << endl;
?? ?swap(c2, c3);
?? ?Print("使用swap(c1,c2)交換后c2中元素", c2);
?? ?Print("使用swap(c1,c2)交換后c3中元素", c3);
?? ?cout << "現(xiàn)在使用另外一種交換方法交換回來(lái):" << endl;
?? ?c2.swap(c3);
?? ?Print("使用c1.swap(c2)交換后c2中元素", c2);
?? ?Print("使用c1.swap(c2)交換后c3中元素", c3);
?? ?cout << endl;
?
?? ?cout << "第三種:" << endl;
?? ?vector<int> c4;
?? ?vector<int> c5;
?? ?vector<int> c6;
?? ?list<int> c7 = { 1,3,1,4 };
?? ?cout << "使用assign將c7中的元素拷貝到c4中:" << endl;
?? ?c4.assign(c7.cbegin(), c7.cend());
?? ?Print("現(xiàn)在c4中的元素為", c4);
?? ?cout << "使用assign將c5初始化為{7,4,1,7,4,1}:" << endl;
?? ?c5.assign({ 7,4,1,7,4,1 });
?? ?Print("現(xiàn)在c5中的元素為", c5);
?? ?cout << "使用assign將c6初始化為7個(gè)1" << endl;
?? ?c6.assign(7, 1);
?? ?Print("現(xiàn)在c6中的元素為", c6);
?? ?cout << "\n\n";
?
?? ?cout << "第二類(lèi):" << endl;
?? ?cout << "第一種:" << endl;
?? ?cout << "使用push_back()在c1后面添加數(shù)字10:" << endl;
?? ?int num1 = 10;
?? ?c1.push_back(num1);//或者直接c1.push_back(10);
?? ?Print("現(xiàn)在c1中的內(nèi)容變成了", c1);
?
?? ?cout << "使用emplace_back()在c1后面添加數(shù)字11:" << endl;
?? ?int num2 = 11;
?? ?c1.emplace_back(num2);//或者直接c1.emplace_back(11);
?? ?Print("現(xiàn)在c1中的內(nèi)容變成了", c1);
?? ?cout << endl;
?
?? ?cout << "第二種" << endl;
?? ?cout << "使用insert()在c1的第三項(xiàng)之前插入新的數(shù)字100:" << endl;
?? ?auto v1 = c1.cbegin() + 2;
?? ?v1=c1.insert(v1, 100);
?? ?cout <<"新添加的元素是"<< *v1<<endl;
?? ?Print("現(xiàn)在c1中的內(nèi)容變成了", c1);
?
?? ?cout << "使用emplace()在c1的第三項(xiàng)之前插入新的數(shù)字200:" << endl;
?? ?v1 = c1.emplace(v1, 200);
?? ?cout << "新添加的元素是" << *v1 << endl;
?? ?Print("現(xiàn)在c1中的內(nèi)容變成了", c1);
?? ?cout << endl;
?
?? ?cout << "第三種" << endl;
?? ?cout << "使用insert()在c1的第三項(xiàng)之前插入4個(gè)300:" << endl;
?? ?auto v2 = v1;
?? ?v2 = c1.insert(v2, 4, 300);
?? ?cout << "新添加的元素是4個(gè)" << *v2 << endl;
?? ?Print("現(xiàn)在c1中的內(nèi)容變成了", c1);
?
?? ?cout << "使用insert()在c1的第三項(xiàng)之前插入容器c3中的第3到7項(xiàng):" << endl;
?? ?auto v3 = v2;
?? ?v3 = c1.insert(v3, c3.cbegin() + 2, c3.cbegin() + 6);
?? ?cout << "新添加的元素是";
?? ?for (auto x = c3.cbegin() + 2;x != c3.cbegin() + 6;++x) {
?? ??? ?cout << *x << " ";
?? ?}
?? ?cout << endl;
?? ?Print("現(xiàn)在c1中的內(nèi)容變成了", c1);
?
?? ?cout << "使用insert()在c1的第三項(xiàng)之前插入{400,500,600,700}"<<endl;
?? ?auto v4 = v3;
?? ?v4 = c1.insert(v4, { 400,500,600,700 });
?? ?cout << "新插入的元素是";
?? ?for (auto i = c1.cbegin() + 2;i != c1.cbegin() + 6;++i) {
?? ??? ?cout << *i << " ";
?? ?}
?? ?cout << endl;
?? ?Print("現(xiàn)在c1中的內(nèi)容變成了", c1);
?? ?cout << "\n\n";
?
?? ?cout << "第三類(lèi)" << endl;
?? ?cout << "第一種" << endl;
?? ?cout << "使用pop_back()在c1后面刪除一個(gè)元素:" << endl;
?? ?c1.pop_back();
?? ?Print("現(xiàn)在c1中的內(nèi)容變成了", c1);
?? ?cout << endl;
?
?? ?cout << "第二種"<<endl;
?? ?cout << "使用erase()刪除c1的第三項(xiàng):" << endl;
?? ?int d = *(c1.cbegin() + 2);
?? ?auto v5=c1.erase(c1.cbegin() + 2);
?? ?cout << "刪除的元素是" << d << ",現(xiàn)在迭代器v5指向的元素是"<<*v5<<endl;
?? ?Print("現(xiàn)在c1中的內(nèi)容變成了", c1);
?? ?cout << endl;
?
?? ?cout << "第三種" << endl;
?? ?cout << "使用erase()刪除c1從第5項(xiàng)到10項(xiàng)的全部元素:" << endl;
?? ?cout << "刪除的元素是:";
?? ?for (auto i = c1.cbegin() + 4;i != c1.cbegin() + 9;++i) {
?? ??? ?cout << *i << " ";
?? ?}
?? ?cout << endl;
?? ?c1.erase(c1.cbegin() + 4, c1.cbegin() + 9);
?? ?
?? ?cout << "使用clear()清空c1中的所有元素:" << endl;
?? ?c1.clear();
?? ?cout << "c1現(xiàn)在是空的嗎?";
?? ?if (c1.empty()) {
?? ??? ?cout << "是的" << endl;
?? ?}
?? ?else
?? ?{
?? ??? ?cout << "不是" << endl;
?? ?}
?? ?
?? ?system("pause");
}
運(yùn)行結(jié)果:
?
2.list
(1)初始化方法
對(duì)于list的初始化,與vector完全相同,這里不再重復(fù)
(2)訪問(wèn)方法
相比于vector,list不支持隨機(jī)訪問(wèn),即使用下標(biāo)訪問(wèn)和使用at()成員函數(shù)是無(wú)效的。還有一個(gè)重要的區(qū)別就是list的迭代器僅支持++、--和*運(yùn)算,對(duì)于兩個(gè)迭代器的差和迭代器和數(shù)字運(yùn)算是不支持的。
(3)修改方法
修改方法除了支持vector的全部操作以外,還有兩個(gè)新的操作,就是在容器頭部進(jìn)行插入
具體有兩種方法,分別是
push_front和emlace_front
代碼示例
#include<iostream>
#include<cstdlib>
#include<string>
#include<list>
?
using namespace std;
?
void Print(string name, list<int> ilist) {
?? ?cout << name << ":";
?? ?for (auto x : ilist) {
?? ??? ?cout << x << " ";
?? ?}
?? ?cout << endl;
}
?
int main() {
?? ?list<int> c1 = { 1,2,3,4,5,6,7 };
?? ?Print("當(dāng)前c1中的元素為", c1);
?? ?cout << "使用push_front()在c1前面插入一個(gè)數(shù)字0:" << endl;
?? ?c1.push_front(0);
?? ?Print("當(dāng)前c1中的元素為", c1);
?? ?cout << "使用emplace_front()在c1前面插入一個(gè)數(shù)字-1:" << endl;
?? ?c1.emplace_front(-1);
?? ?Print("當(dāng)前c1中的元素為", c1);
?? ?system("pause");
}
運(yùn)行結(jié)果:
3.deque
deque除了支持vector的全部操作,還支持前插操作(即使用push_front和emplace_front方法)
4.array
對(duì)于array來(lái)說(shuō),容器一經(jīng)定義其大小就是固定的了。所以定義的時(shí)候要指明其大小。
(1)定義和初始化
定義和初始化
對(duì)于array來(lái)說(shuō),定義和初始化的操作分為三種,
????第一種是定義一個(gè)沒(méi)有賦任何值得“空”數(shù)組;
????第二種是定義為一個(gè)其他容器的副本;
????第三種就是定義為一個(gè)初始化列表中的元素;
對(duì)比于vector,array不支持同時(shí)賦多個(gè)同樣的值,另外還不支持迭代器范圍賦值
具體方法為:(以int為例)
????第一種 array<int,3> a1;
????第二種 array<int,3> a2(a1);????array<int,3> a3=a1;
????第三種 array<int,3> a4{1,2,3};????array<int,3> a5={1,2,3};
代碼示例:
#include<iostream>
#include<cstdlib>
#include<string>
#include<array>
?
using namespace std;
?
void Print(string name,array<int, 3> iarray) {
?? ?cout << name << ":";
?? ?for (auto x : iarray) {
?? ??? ?cout << x << " ";
?? ?}
?? ?cout << endl;
}
?
int main() {
?? ?array<int, 3> a1;
?
?? ?array<int, 3> a2{ 1,2,3 };
?? ?array<int, 3> a3 = { 4,5,6 };
?
?? ?array<int, 3> a4(a2);
?? ?array<int, 3> a5 = a3;
?
?? ?Print("a2", a2);
?? ?Print("a3", a3);
?? ?Print("a4", a4);
?? ?Print("a5", a5);
?? ?system("pause");
}
運(yùn)行結(jié)果:
(2)訪問(wèn)容器
和vector完全一樣,這里不再贅述
(3)修改容器
array是一個(gè)長(zhǎng)度固定的數(shù)組,因此所有修改容器的操作都不能改變?nèi)萜鞯拇笮?/p>
以下是關(guān)于array的操作分類(lèi),一共有二類(lèi):
????第一類(lèi):對(duì)已經(jīng)定義好的array進(jìn)行賦值
????第二類(lèi):對(duì)兩個(gè)array中的內(nèi)容進(jìn)行交換
其中賦值操作是通過(guò)"="號(hào)進(jìn)行實(shí)現(xiàn)的,注意進(jìn)行賦值一定要保證array類(lèi)型的完全相同。
而交換是使用swap方法,也是有兩種。
具體代碼也不再一一展示
5.forward_list
這是一種前插式單向鏈表,不支持后插操作,也不支持從后向前遍歷
(1)定義和初始化
初始化方法與vector完全一樣,這里不再贅述
(2)訪問(wèn)容器
由于是前插式的鏈表,所以就沒(méi)有反向遍歷這種操作,因此也就不存在反向迭代器。另外一個(gè)值得注意的地方是forward_list沒(méi)有size()方法,因此要想正向遍歷一個(gè)forward_list容器,就只有兩種可選的方式,一種是使用正向迭代器,另一種就是使用范圍for語(yǔ)句。
因?yàn)樾枰诖吮淼那安坎迦胍恍﹥?nèi)容,所以還定義了一個(gè)指向表的首元素之前的一個(gè)不存在元素的一個(gè)迭代器,以便于在表的頭部插入數(shù)據(jù)。
具體方法為
lst.before_begin()和lst.cbefore_begin()
(3)修改容器
根據(jù)修改數(shù)據(jù)方式的不同,可以分為兩類(lèi)
????第一類(lèi)是插入數(shù)據(jù),有四種方法
????????第一種是在某個(gè)迭代器之后插入一個(gè)元素;
????????第二種是在某個(gè)尾后迭代器之后插入n個(gè)值;
????????第三種是在某個(gè)尾后迭代器之后插入另一個(gè)容器某一迭代器范圍內(nèi)的元素;
????????第四種是在某個(gè)迭代器之后插入一個(gè)初始化列表中的元素;
????第二類(lèi)是刪除數(shù)據(jù),有兩種方法
????????第一種是刪除某個(gè)迭代器之后的數(shù)據(jù)
????????第二種是刪除某個(gè)迭代器之間的數(shù)據(jù),不包括前迭代器的元素,但是包括后迭代器指向的元素
具體為:
????第一類(lèi)
????????第一種:lst.insert_after(p,t)和lst.emplace_after(p,args);
????????第二種:lst.insert_sfter(p,n,t);
????????第三種:lst.insert_after(p,b,e);
????????第四種:lst.insert_after(p,il);
????第二類(lèi)
????????第一種:lst.erase_after(p);
????????第二種:lst.erase_after(b,e);
代碼示例:
#include<iostream>
#include<cstdlib>
#include<forward_list>
#include<vector>
#include<string>
?
using namespace std;
?
void Print(string name, const forward_list<int> &iflist) {
?? ?cout << name << ":";
?? ?for (auto x : iflist) {
?? ??? ?cout << x << " ";
?? ?}
?? ?cout << endl;
}
?
int main() {
?? ?forward_list<int> c1 = { 1,2,3,4,5,6,7 };
?? ?vector<int> c2(c1.begin(), c1.end());
?
?? ?cout << "第一類(lèi):" << endl;
?? ?cout << "在c1前面插入一個(gè)元素0" << endl;
?? ?c1.insert_after(c1.cbefore_begin(),0);
?? ?Print("現(xiàn)在c1中的元素為", c1);
?? ?cout << "在c1前面再插入5個(gè)-1" << endl;
?? ?c1.insert_after(c1.cbefore_begin(), 5, -1);
?? ?Print("現(xiàn)在c1中的元素為", c1);
?? ?cout << "在c1前面插入c2的第二到5個(gè)位置的元素" << endl;
?? ?c1.insert_after(c1.before_begin(), c2.begin() + 1, c2.begin() + 5);
?? ?Print("現(xiàn)在c1中的元素為", c1);
?? ?cout << "在c1前面插入列表{100,200,300}中的元素" << endl;
?? ?c1.insert_after(c1.cbefore_begin(), { 100,200,300 });
?? ?Print("現(xiàn)在c1中的元素為", c1);
?
?? ?cout << "\n\n";
?? ?cout << "第二種" << endl;
?? ?cout << "將c1的首元素刪除" << endl;
?? ?c1.erase_after(c1.cbefore_begin());
?? ?Print("現(xiàn)在c1中的元素為", c1);
?
?? ?auto i1 = c1.before_begin();
?? ?auto i3 = c1.begin();
?? ?for (int i = 0; i < 10; ++i) {
?? ??? ?++i3;
?? ?}
?? ?cout << "刪除c1前面10個(gè)元素" << endl;
?? ?cout << "被刪除的元素為:" << endl;
?? ?for (auto i = c1.begin(); i != i3; ++i) {
?? ??? ?cout << *i << " ";
?? ?}
?? ?cout << endl;
?
?? ?c1.erase_after(i1, i3);
?? ?Print("現(xiàn)在c1中的元素為", c1);
?
?? ?system("pause");
}
運(yùn)行結(jié)果:
6.string
string可以看作是一個(gè)char型的vector容器,除了支持與vector<char>的全部操作外,還有額外的定義,訪問(wèn)和修改的方法。
以下只敘述string相比于vector<char>的額外的操作
這些操作的類(lèi)型要么是提供string類(lèi)與c風(fēng)格字符數(shù)組之間的相互轉(zhuǎn)換,要么是增加了允許我們使用下標(biāo)代替迭代器的版本
(1)構(gòu)造string的其他方法
構(gòu)造string的新方法可以分為兩種:
????第一種是提供從c風(fēng)格字符數(shù)組來(lái)進(jìn)行初始化的一個(gè)方法;
????第二種是提供從另一個(gè)string對(duì)象的下標(biāo)計(jì)算的部分初始化方法;
具體分別是:
????第一種:string s(cp,n);(新的string對(duì)象會(huì)被初始化為cp數(shù)組前n個(gè)字符)
????第二種:string s(s2,pos2);????string s(s2,pos2,len2); ????或者使用substr(eg:string s=s2.substr(0,5);<前閉后開(kāi)>,如果只有一個(gè)參數(shù),表明從某位置開(kāi)始截取,一直到串尾,如果沒(méi)有參數(shù),則等同于"="號(hào))。
程序示例:
#include<iostream>
#include<cstdlib>
#include<string>
?
using namespace std;
?
int main() {
?? ?const char a[20] = "hello world!!!";
?? ?cout << "a:" << a << endl;
?? ?cout << "將s1中的內(nèi)容初始化為a的前12個(gè)字符" << endl;
?? ?string s2(a, 12);
?? ?cout << "s2:" << s2 << endl;
?
?? ?cout << "將s3初始化為s2從下標(biāo)6開(kāi)始后的所有字符:" << endl;
?? ?string s3(s2, 6);
?? ?cout << "s3:" << s3 << endl;
?
?? ?cout << "將s4初始化為s3從下標(biāo)0開(kāi)始后的5個(gè)字符:" << endl;
?? ?string s4(s3, 0, 5);
?? ?cout << "s4:" << s4 << endl;
?
?? ?cout << "使用substr將s5初始化為s2從下標(biāo)6開(kāi)始的所有字符:" << endl;
?? ?string s5 = s2.substr(6);
?? ?cout << "s5:" << s5 << endl;
?
?? ?cout << "使用substr將s6初始化為s5從下標(biāo)0開(kāi)始后的5個(gè)字符:" << endl;
?? ?string s6 = s5.substr(0, 5);
?? ?cout << "s6:" << s6 << endl;
?
?? ?cout << "如果substr沒(méi)有參數(shù),則等同于\"=\"號(hào):" << endl;
?? ?string s7 = s2.substr();
?? ?cout << "s7:" << s7 << endl;
?
?? ?system("pause");
}
運(yùn)行結(jié)果:
?(2)改變string的其他方法
string為了與c風(fēng)格字符數(shù)組兼容以及支持使用下標(biāo)來(lái)進(jìn)行字符串的操作,重載了assign,insert和erase,另外還定義了append和replace兩個(gè)函數(shù)用來(lái)追加和替換容器。
具體分別是:
s.insert(pos,args) 在pos之前插入args指定的字符,pos可以是一個(gè)下標(biāo)或一個(gè)迭代器。接受下標(biāo)的版本返回一個(gè)指向s的引用;接受迭代器的版本返回指向第一個(gè)插入字符的迭代器。
s.erase(pos,len) 刪除從位置pos開(kāi)始的len個(gè)字符。如果len被省略,則刪除從pos開(kāi)始直至s末尾的所有字符。返回一個(gè)指向s的引用。
s.assign(args)????將s中的字符替換為args指定的字符。返回一個(gè)指向s的引用。
s.append(args) 將args追加到s。返回一個(gè)指向s的引用。
s.replace(range,args) 刪除s中范圍range內(nèi)的字符,替換為args指定的字符。range或者是一個(gè)下標(biāo)和一個(gè)長(zhǎng)度,或者是一對(duì)指向s的迭代器。返回一個(gè)指向s的引用。
args可以是下列形式之一;append和assign可以使用所有形式
str不能與s相同,迭代器b和e不能指向s
str 字符串str
str,pos,len????str中從pos開(kāi)始最多l(xiāng)en個(gè)字符
cp,len????從cp指向的數(shù)組前(最多)len個(gè)字符
cp????cp指向的以空字符結(jié)尾的字符數(shù)組
n,c????n個(gè)字符c
b,e????迭代器b和e指定范圍內(nèi)的元素
初始化列表。
replace和insert所允許的args形式依賴(lài)于range和pos是如何指定的
replace(pos,len,args)?? ?replace(b,e,args)?? ?insert(pos,args)?? ?insert(iter,args)?? ?args可以是
??? ???? ???? ???? ?str
??? ???? ???? ???? ?str,pos,len
??? ???? ???? ???? ?cp,len
??? ???? ???? ???? ?cp
??? ???? ???? ???? ?n,c
??? ???? ???? ???? ?b2,e2
??? ???? ???? ???? ?初始化列表
示例代碼:
#include<iostream>
#include<string>
#include<cstdlib>
?
using namespace std;
?
int main() {
?? ?string s("hello");
?? ?
?? ?//insert與erase:
?? ?cout << "s:" << s << endl;
?? ?//insert(pos,n,c)
?? ?s.insert(s.size(), 5, '!');//在s后面插入5個(gè)'!'
?? ?cout << "s:" << s << endl;
?? ?//erase(pos,len)
?? ?s.erase(s.size() - 5, 5);//在s后面刪除5個(gè)字符
?? ?cout << "s:" << s << endl << endl;
?
?? ?cout << endl;
?
?? ?//assign與insert:(c語(yǔ)言風(fēng)格字符串風(fēng)格)
?? ?const char *cp = "Stately,plump Buck";
?? ?//assign(cp,len)
?? ?s.assign(cp, 7);//s="Stately"
?? ?cout << "s:" << s << endl;
?? ?//insert(cp,len)
?? ?s.insert(s.size(), cp + 7);//s="Stately,plump Buck"
?? ?cout << "s:" << s << endl;
?
?? ?cout << endl;
?
?? ?//inser(字符串)
?? ?string s2 = "some string", s3 = "some other string";
?? ?cout << "s2:" << s2 << endl;
?? ?cout << "s3:" << s3 << endl;
?? ?//insert(pos,str)
?? ?s2.insert(0, s3);
?? ?cout << "s2:" << s2 << endl;
?? ?//insert(pos,str,pos,len)
?? ?s2.insert(0, s3, 0, s3.size());
?? ?cout << "s2:" << s2 << endl;
?
?? ?cout << endl;
?
?? ?//append與replace
?? ?string s4("C++ Primer"), s5 = s4;
?? ?s4.insert(s4.size(), " 5th Ed");//s4="C++ Primer 5th Ed"
?? ?s4.append(" 5th Ed");//與上面等價(jià)
?? ?cout << "s4:" << s4 << endl;
?? ?cout << "s5:" << s5 << endl;
?
?? ?//將5th替換為6th
?? ?s4.erase(11, 3);
?? ?s4.insert(11, "6th");
?? ?s4.replace(11, 3, "6th");//與上面等價(jià)
?? ?s4.replace(11, 3, "sixth");
?? ?cout << "s4:" << s4 << endl;
?
?
?? ?system("pause");
}
運(yùn)行結(jié)果
(3)string搜索操作
string類(lèi)提供了6個(gè)不同的搜索,每個(gè)搜索操作有4個(gè)重載版本,如果搜索成功,都返回匹配位置的下標(biāo),如果搜索失敗,則返回一個(gè)非常大的整數(shù)
6種搜索操作分別是:
????第一種:尋找s中args第一次出現(xiàn)的位置;
????第二種:尋找s中args最后一次出現(xiàn)的位置;
????第三種:在s中查找args任何一個(gè)字符第一次出現(xiàn)的位置
????第四種:在s中查找args任何一個(gè)字符最后一次出現(xiàn)的位置
????第五種:在s中查找第一個(gè)不在args中出現(xiàn)的字符
????第六種:在s中查找最后一個(gè)不在args中出現(xiàn)的字符
具體分別是:
????第一種:s.find(args);
????第二種:s.rfind(args);
????第三種:s.find_first_of(args);
????第四種:s.find_last_of(args);
????第五種:s.find_first_not_of(args);
????第六種:s.find_last_not_of(args);
args必須是以下形式之一?? ?功能描述
c,pos?? ?從s中位置pos開(kāi)始查找字符c。pos默認(rèn)為0
s2,pos
從s中位置pos開(kāi)始查找字符串s2.pos默認(rèn)為0
cp,pos?? ?相當(dāng)于s換成了字符數(shù)組cp
cp,pos,n?? ?
相當(dāng)于s換成了字符數(shù)組cp
????代碼示例1:
#include<iostream>
#include<cstdlib>
#include<string>
?
using namespace std;
?
//尋找某子串在主串中的數(shù)量,使用string的find()方法
int findAmount(const string &str, const string &childStr) {
?? ?auto x = str.find(childStr);
?? ?if ( x > str.size()) {
?? ??? ?return 0;//如果str中不存在childStr,那么x會(huì)是一個(gè)超級(jí)大的整數(shù),此時(shí)返回0;
?? ?}else{
?? ??? ?string temp(str, x + 1, str.size() - x - 1);//遞歸搜索后面的字符串
?? ??? ?return 1+findAmount(temp, childStr);
?? ?}
}
?
int main() {
?
?? ?string s1 = "aacvcaa aacvcaa aacvcaa aacvcaa";
?? ?string s2 = "cvc";
?? ?cout <<"子串"<<s2<<"在主串"<<s1<<"中的數(shù)量為"<<findAmount(s1, s2)<<endl;
?? ?system("pause");
}
運(yùn)行結(jié)果1:
代碼示例2:
#include<iostream>
#include<string>
#include<cstdlib>
?
using namespace std;
?
int main() {
?
?? ?string name("AnnaBelle");
?? ?auto pos1 = name.find("Anna");
?? ?cout << "pos1:" << pos1 << endl;
?
?? ?cout << endl;
?
?? ?//大小寫(xiě)敏感
?? ?string lowercase("annabelle");
?? ?pos1 = lowercase.find("Anna");
?? ?cout << "pos1:" << pos1 << endl;
?
?? ?string numbers("0123456789"), name1("r2d2");
?? ?auto pos = name1.find_first_of(numbers);
?? ?cout << "pos:" << pos << endl;
?
?? ?string dept("03714p3");
?? ?auto pos2 = dept.find_first_not_of(numbers);
?? ?cout << "pos2:" << pos2 << endl;
?
?? ?cout << endl;
?
?? ?//指定位置搜索
?? ?string::size_type pos3 = 0;
?? ?while ((pos3 = name1.find_first_not_of(numbers, pos3)) != string::npos) {
?? ??? ?cout << "在" << pos3 << "處發(fā)現(xiàn)數(shù)字" << name1[pos3] << endl;
?? ??? ?++pos3;
?? ?}
?
?? ?cout << endl;
?
?? ?//逆向搜索
?? ?string river("Mississippi");
?? ?auto first_pos = river.find("is");
?? ?cout << "first_pos:" << first_pos << endl;
?
?? ?auto last_pos = river.rfind("is");
?? ?cout << "last_pos:" << last_pos << endl;
?
?? ?system("pause");
}
運(yùn)行結(jié)果:
(4)string的compare函數(shù)
字符串的比較就是使用字典序比較,沒(méi)什么可說(shuō)的
返回值分三種,若s小于目標(biāo)串,則返回負(fù)數(shù),相等返回0,大于則返回正數(shù)。
使用方法為s.compare(args);
args可以是以下幾種形式之一:
s2:比較s與s2
pos1,n1,s2:將s中從pos1開(kāi)始的n1個(gè)字符與s2進(jìn)行比較
pos1,n1,s2,pos2,n2:將s中從pos1開(kāi)始的n1個(gè)字符與s2從pos2開(kāi)始的n2個(gè)字符進(jìn)行比較
cp:與c風(fēng)格字符串比較
pos1,n1,cp:從pos1開(kāi)始的n1個(gè)字符與cp比較
?
pos1,n1,cp,n2:從pos1開(kāi)始的n1個(gè)字符與cp后的n2個(gè)字符進(jìn)行比較
代碼示例:
#include<iostream>
#include<string>
#include<cstdlib>
?
using namespace std;
?
int main() {
?? ?const char *cp = "zzc_hello_world!";
?? ?string s1 = "ddfg_hello_world!!!";
?? ?string s2 = "jjjiur_hello_world!!";
?? ?
?? ?if (s1.compare(5, 5, s2, 7, 5) == 0) {
?? ??? ?cout << "局部相等" << endl;
?? ?}else {
?? ??? ?cout << "局部不相等" << endl;
?? ?}
?
?? ?if (s1.compare(5, 5, cp + 5, 5)) {
?? ??? ?cout << "局部相等" << endl;
?? ?}else {
?? ??? ?cout << "局部不相等" << endl;
?? ?}
?
?? ?system("pause");
}
運(yùn)行結(jié)果:
(5)string與數(shù)值之間進(jìn)行轉(zhuǎn)換的方法
字符串與數(shù)值之間的轉(zhuǎn)換,分兩種情況,字符串轉(zhuǎn)數(shù)值與數(shù)值轉(zhuǎn)字符串:
其中字符串轉(zhuǎn)數(shù)值又分為轉(zhuǎn)為整型數(shù)或浮點(diǎn)型數(shù)
to_string(val)轉(zhuǎn)字符串,有各種重載
?
stoi(s,p,b); string->int
stol(s,p,b); string->long
stoul(s,p,b); string->unsigned long
stoll(s,p,b); string->long long
stoull(s,p,b); string->unsigned long long
其中p是s中第一個(gè)數(shù)字字符,默認(rèn)為0,b是使用的進(jìn)制,默認(rèn)為10
?
stof(s,p); string->float
stod(s,p); string->double
stold(s,p); string->long double
s,p同上
示例代碼:
#include<iostream>
#include<string>
#include<cstdlib>
?
using namespace std;
?
int main() {
?? ?int i = 42;
?? ?string s = to_string(i);
?? ?double d = i + 0.5;
?? ?string s2 = to_string(d);
?? ?double d2 = stod(s2);
?? ?cout << "s:" << s << endl;
?? ?cout << "d2:" << d2 << endl;
?
?? ?string s3 = "PI=3.1415";
?? ?double d3 = stod(s3.substr(s3.find_first_of("+-.0123456789")));
?? ?cout << "d3:" << d3 << endl;
?? ?system("pause");
}
運(yùn)行結(jié)果:
7.在文章的最開(kāi)始,我們提到了c++還為這些順序容器提供了三種適配器,所謂適配器,就是使容器的行為看起來(lái)像其他的存儲(chǔ)結(jié)構(gòu)一樣,即棧,普通隊(duì)列和優(yōu)先隊(duì)列,優(yōu)先隊(duì)列就是按照某種規(guī)則排序的隊(duì)列。(stack,queue,priority_queue)
?
首先介紹所有適配器都具有的字段和函數(shù):
介紹就不說(shuō)了,都可以顧名思義:
size_type;????value_type;????container_type;(這個(gè)是實(shí)現(xiàn)適配器的底層類(lèi)型)????A a;(定義一個(gè)適配器)
A a(c);適配器帶有c容器的拷貝????關(guān)系運(yùn)算 ==,!=,<,<=,>,>=????a.empty();????a.size();????a.swap(b)????swap(a,b);
默認(rèn)情況下stack和queue是基于deque實(shí)現(xiàn)的,priority_queue是基于vector實(shí)現(xiàn)的
當(dāng)然他們都可以指定實(shí)現(xiàn)的容器:
例如:用list實(shí)現(xiàn)一個(gè)棧,則可以這樣寫(xiě):
stack<int,list<int>> istk_list;
其他的類(lèi)似
其中需要注意的是:
stack可以使用除array和forward_list以外的容器,queue相比stack不可使用vector,priority_queue相比stack不可使用list
?
下面是棧特有的操作:
s.pop(); 出棧,但不返回棧頂元素
s.push(item);????進(jìn)棧
s.emplace(args);????進(jìn)棧
s.top();????返回棧頂元素
?
下面是隊(duì)列特有的操作:
q.pop();????出隊(duì)列,但不返回棧頂元素
q.front();????返回首元素
q.back();????返回尾元素
q.push(item);????進(jìn)隊(duì)列
q.emplace(args);????進(jìn)隊(duì)列
其中優(yōu)先隊(duì)列不支持上面的back()操作,而優(yōu)先隊(duì)列還另外支持一個(gè)q.top()操作
下面是一個(gè)示例:
代碼:
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<cstdlib>
?
using namespace std;
?
int main() {
?? ?vector<string> s{ "123", "456", "789" };
?? ?stack<string, vector<string>> str_stk(s);
?? ?cout << "棧str_stk的棧頂元素:" << str_stk.top() << endl << endl;;
?
?? ?stack<int> intStack;
?? ?int value;
?? ?for (size_t ix = 0; ix != 10; ++ix) {
?? ??? ?intStack.push(ix);
?? ?}
?? ?while (!intStack.empty()) {
?? ??? ?value = intStack.top();
?? ??? ?cout << value << " ";
?? ??? ?intStack.pop();
?? ?}
?? ?cout << endl << "棧空!" << endl;
?? ?
?? ?system("pause");
}
運(yùn)行結(jié)果:
?
常用的順序容器以及操作至此已全部敘述完畢:下面來(lái)看一看什么情況下應(yīng)該選取什么樣的容器才是最合適的:
1.首選vector,如果是字符操作和字符串操作,首選string
2.如果程序中有許多小的元素,而且可用空間不是很樂(lè)觀,則不要使用list或者forward_list
3.如果程序會(huì)隨機(jī)訪問(wèn)容器中的元素,則應(yīng)該使用vector或者deque
4.如果程序會(huì)頻繁的在容器中間插入或者刪除數(shù)據(jù),則優(yōu)先考慮使用list或者forward_list
5:如果程序只會(huì)頻繁的在容器的頭部和尾部進(jìn)行數(shù)據(jù)的插入和刪除,則應(yīng)優(yōu)先考慮使用deque
6:如果要先進(jìn)行頻繁改變后又進(jìn)行頻繁的隨機(jī)訪問(wèn),則有以下兩種推薦方案:
1)考慮使用assign方法將list或者forward_list中的元素拷貝到vectoe或者deque中再進(jìn)行操作
2)如果要進(jìn)行對(duì)輸入數(shù)據(jù)進(jìn)行即時(shí)排序,則應(yīng)考慮在vector尾后添加元素后再調(diào)用sort方法進(jìn)行排序。
7:如果既需要頻繁的中間插入,又需要頻繁的隨機(jī)讀取,則使用概率統(tǒng)計(jì)方法統(tǒng)計(jì)出哪種操作所占比重較大,則優(yōu)先考慮使用哪種有利于占比較大操作的容器,如果有時(shí)候兩種操作比重差不多大,則應(yīng)該進(jìn)行運(yùn)行時(shí)間測(cè)試,從而確定最佳容器以及最佳方案。
?
總結(jié)
以上是生活随笔為你收集整理的C++容器的选择和详细操作方法总结(有自己总结)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: c++ stl 标准库容器的选择原则(图
- 下一篇: C++ vector容器删除操作