1、關聯容器和順序容器
C++中有兩種類型的容器:順序容器和關聯容器,順序容器主要有:vector、list、deque等。關聯容器主要有map和set。如下圖:
1、vector基本使用

#include <iostream> #include <stdlib.h> #include <string.h> #include <algorithm> #include <vector> using namespace std; //利用模版進行輸出 template <typename T> void print(vector<T> a) { //輸出方法1 for(auto i:a) { cout<<i<<'\t'; } cout<<endl; //輸出方法2 typename vector<T>::iterator it;//前面要加typename,要不會出錯 for(it=a.begin();it!=a.end();it++) { cout<<*it<<'\t'; } cout<<endl; //輸出方法3,這里只是想說這樣也可以輸出 cout<<a[0]<<'\t'<<a[1]<<'\t'<<a[2]<<'\t'<<a[3]<<'\t'<<a[4]<<endl; cout<<"********************"<<endl; } int main() { /*vector初始化對象*/ vector<int> v1;//v1是一個空的vector,潛在的元素是int類型,執行時,默認初始化 v1={1,2,3,4,5}; print(v1); vector<int> v2(v1);//相當於vector<int> v2=v1 print(v2); vector<char> v3(5,'a');//v3中含有5個a字符 print(v3); vector<string> v4{"aa","ss","dd","ff","gg"};//v4賦值 print(v4); vector<float> v5(5);//出事化v5,為5個0.0 v5[0]=1.1; // v5[6]=8.8; vector可以利用下標訪問,但是不能使用下標添加元素 print(v5); /*-------------------------------------------------------------------------------*/ /*vector操作*/ vector<string> v6; if(v6.empty())//vector是否為空 { cout<<"------"<<"v6 is empty"<<"-------"<<endl; } string s="qwe"; for(int i=0;i<5;i++) { v6.push_back(s);//末尾添加一個元素 } v6.pop_back();//末尾刪除一個 v6.push_back("1234"); print(v6); cout<<"------"<<"v6的長度為:"<<v6.size()<<"------"<<endl; v6=v4;//拷貝v4中的元素賦值到v6中 if(v6==v4) { cout<<"------"<<"v6==v4"<<"------"<<endl; } /*-------------------------------------------------------------------------------*/ /*vector常用操作*/ vector<int> array={1,6,2,6,3,6,4,6,5,6}; array.erase(remove(array.begin(),array.end(),6),array.end());//需添加頭文件algorithm /*remove函數使用: *remove(始地址,終地址,需要移除的元素),返回是被替換的數第一個數的地址,比如本題vector *原始數組為:[1,6,2,6,3,6,4,6,5,6],使用remove函數后為[1,2,3,4,5,6,4,6,5,6], *返回的地址為位置5上(0開始)的6的地址,如下輸出數字5. cout<<*(remove(array.begin(),array.end(),6)-1)<<endl;*/ /*刪除6的另一種方法 vector<int>::iterator it1; it1=array.begin(); for(it1=array.begin();it1!=array.end();it1++) { if(6==*it1) { array.erase(it1);//刪除掉it1時,it1會指向下一個數,也就是6,然后再自加會指向下一個6,也就是鄰接的6是刪除不掉的 it1--;//加上這一句就不會出錯 } }*/ print(array); vector< vector<int> > intVV;//vector實現二維數組 vector<int> intV; int i,j; for(i=0;i<3;++i){ intV.clear(); for(j=0;j<5;++j) intV.push_back(i*10+j); intVV.push_back(intV); } for(i=0;i<3;++i){ for(j=0;j<5;++j) cout<<intVV[i][j]<<'\t'; cout<<endl; } return 0; }
2、list基本使用
Lst1.assign() 給list賦值
Lst1.back() 返回最后一個元素
Lst1.begin() 返回指向第一個元素的迭代器
Lst1.clear() 刪除所有元素
Lst1.empty() 如果list是空的則返回true
Lst1.end() 返回末尾的迭代器
Lst1.erase() 刪除一個元素
Lst1.front() 返回第一個元素
Lst1.insert() 插入一個元素到list中
Lst1.pop_back() 刪除最后一個元素
Lst1.pop_front() 刪除第一個元素
Lst1.push_back() 在list的末尾添加一個元素
Lst1.push_front() 在list的頭部添加一個元素
Lst1.rbegin() 返回指向第一個元素的逆向迭代器
Lst1.remove() 從list刪除元素
Lst1.rend() 指向list末尾的逆向迭代器
Lst1.reverse() 把list的元素倒轉
Lst1.size() 返回list中的元素個數
Lst1.sort() 給list排序
Lst1.unique() 刪除list中重復的元素

#include <iostream> #include <stdlib.h> #include <string.h> #include <algorithm> #include <list> using namespace std; //利用模版進行輸出 template <typename T> void print(list<T> a) { //輸出方法1 for(auto i:a) { cout<<i<<'\t'; } cout<<endl; //輸出方法2 typename list<T>::iterator it;//前面要加typename,要不會出錯 for(it=a.begin();it!=a.end();it++) { cout<<*it<<'\t'; } cout<<endl; cout<<"********************"<<endl; } int main() { /*list初始化*/ list<int> l1;//定義一個空的list list<int> l2(5,1);//定以一個長度為5的list print(l2); list<char> l3={'a','b','c','d'}; print(l3); list<char> l4(l3);//相當於l4=l3 print(l4); list<char> l5(l3.begin(),l3.end());//同上 print(l5); list<char> l6=l5;//同上 print(l6); /*----------------------------------------------------------------------*/ /*常用操作*/ list<int> array={6,5,4,3,2,1,7}; print(array); array.sort(); print(array); array.reverse(); print(array); cout<<"返回第一個元素:"<<array.front()<<endl; cout<<"返回最后一個元素:"<<array.back()<<endl; cout<<"返回第一個元素迭代器:"<<*(array.begin())<<endl; cout<<"返回最后一個元素迭代器:"<<*(--array.end())<<endl; cout<<"返回第一個元素的逆向迭代器:"<<*(array.rbegin())<<endl; cout<<"返回最后一個元素的逆向迭代器:"<<*(array.rend())<<endl; list<int> array1; array1.assign(array.begin(),array.end());//給list賦值給array1 array1.pop_front();//刪除第一個元素 array1.pop_back();//刪除最后一個元素 print(array1); array1.clear();//刪除所有元素 if(array1.empty())//判斷lsit是否為空 { cout<<"array1 is empty"<<endl; } array1.assign(6,1);//array1={1,1,1,1,1,1} array1.push_front(11);//在list頭插入元素 array1.push_back(13);//在list尾插入元素 print(array1); array1.erase(array1.begin());//擦除list第一個數 array1.erase(--array1.end());//擦除list最后一個數 print(array1); cout<<"array1的長度為:"<<array1.size()<<endl;//array1的長度 array1.insert(++array1.begin(),3,9);//從位置1開始插入3個9 print(array1); array1.remove(9);//移除list中的所有元素9 print(array1); array1.unique();//移除list中重復元素 print(array1); return 0; }
3、deque基本使用

#include <iostream> #include <stdlib.h> #include <string.h> #include <algorithm> #include <deque> using namespace std; //利用模版進行輸出 template <typename T> void print(deque<T> a) { //輸出方法1 for(auto i:a) { cout<<i<<'\t'; } cout<<endl; //輸出方法2 typename deque<T>::iterator it;//前面要加typename,要不會出錯 for(it=a.begin();it!=a.end();it++) { cout<<*it<<'\t'; } cout<<endl; //輸出方法3,這里只是想說這樣也可以輸出 cout<<a[0]<<'\t'<<a[1]<<'\t'<<a[2]<<'\t'<<a[3]<<'\t'<<a[4]<<endl; cout<<"********************"<<endl; } int main() { /*deque初始化操作*/ deque<int> d1(10); for(int i=0;i<8;i++) { d1[i]=i; } print(d1); deque<string> d2(6,"abc");//d2中存在6個abc print(d2); deque<string> d3(d2);//初始化d3=d2 print(d3); /*----------------------------------------------------------------------*/ /*deque基本操作*/ deque<int> array(6,10); array.push_front(1);//頭部插入 array.push_back(2);//尾部插入 array.insert(array.begin()+1,9);//在位置1插入9 print(array); array.pop_front();//頭部刪除 array.pop_back();//尾部刪除 print(array); cout<<"頭元素:"<<array.front()<<'\t'<<"尾元素:"<<array.back()<<'\t'<<"大小:"<<array.size()<<endl; array.erase(++array.begin(),--array.end());//刪除該區間內的元素 print(array); array.clear(); if(array.empty()) { cout<<"array is empty"<<endl; } return 0; }
4、set基本使用
begin()--返回指向第一個元素的迭代器
clear()--清除所有元素
count()--返回某個值元素的個數
empty()--如果集合為空,返回true
end()--返回指向最后一個元素的迭代器
equal_range()--返回集合中與給定值相等的上下限的兩個迭代器
erase()--刪除集合中的元素
find()--返回一個指向被查找到元素的迭代器
get_allocator()--返回集合的分配器
insert()--在集合中插入元素
lower_bound()--返回指向大於(或等於)某值的第一個元素的迭代器
key_comp()--返回一個用於元素間值比較的函數
max_size()--返回集合能容納的元素的最大限值
rbegin()--返回指向集合中最后一個元素的反向迭代器
rend()--返回指向集合中第一個元素的反向迭代器
size()--集合中元素的數目
swap()--交換兩個集合變量
upper_bound()--返回大於某個值元素的迭代器
value_comp()--返回一個用於比較元素間的值的函數

#include <iostream> #include <stdlib.h> #include <string.h> #include <algorithm> #include <set> using namespace std; //利用模版進行輸出 template <typename T> void print(set<T> a) { //輸出方法1 for(auto i:a) { cout<<i<<'\t'; } cout<<endl; //輸出方法2 typename set<T>::iterator it;//前面要加typename,要不會出錯 for(it=a.begin();it!=a.end();it++) { cout<<*it<<'\t'; } cout<<endl; cout<<"********************"<<endl; } int main() { /*set初始化操作*/ set<int> s={11,12,14,15,15};//注意set里面不會存在重復的數 print(s); set<int> s1(s);//s1=s; print(s1); /*----------------------------------------------------------------------*/ /*set基本操作*/ s1.insert(16);//插入一個元素 int a[]={110,17,18,19}; s1.insert(a,a+3);//將a的前3個元素插入set print(s1); cout<<"s1的長度:"<<s1.size()<<'\t' <<"s1的第一個元素:"<<*s1.begin()<<'\t' <<"s1的最后一個元素:"<<*--s1.end()<<'\t'<<'\n'//注意最后位置要減1 <<"s1的最后一個元素:"<<*s1.rbegin()<<'\t' <<"s1的第一個元素:"<<*--s1.rend()<<'\t'//注意最后位置要減1 <<endl; cout<<"s1中11出現的次數是 :"<<s.count(11)<<endl;//因為set保證元素唯一,所以可以判斷數據的存在性 cout<<"s1中第一個大於等於17的數是:"<<*s1.lower_bound(17)<<endl; cout<<"s1中第一個大於17的數是:"<<*s1.upper_bound(17)<<endl; pair<set<int>::const_iterator,set<int>::const_iterator> p; p = s.equal_range(14); cout<<"第一個大於等於14的數是 :"<<*p.first<<'\t' <<"第一個大於14的數是 : "<<*p.second<<endl; set<string> s2={"as","ad","af","ag","ah"}; print(s2); s2.erase(s2.begin());//刪除第一個元素 s2.erase("ad");//刪除對應元素 print(s2); s2.erase(++s2.begin(),--s2.end());//刪除該區間內元素 print(s2); set<string>::iterator iter=s2.find("as");//找到 as 並返回該元素的位置 cout<<*iter<<endl; s2.clear(); if(s2.empty()) { cout<<"s2 is empty"<<endl; } return 0; }
5、棧、隊列的使用
棧:
empty() 堆棧為空則返回真
pop() 移除棧頂元素
push() 在棧頂增加元素
size() 返回棧中元素數目
top() 返回棧頂元素

#include <iostream> #include <stdlib.h> #include <string.h> #include <algorithm> #include <stack> #include <deque> #include <vector> #include <list> using namespace std; //利用模版進行輸出 template <typename T> void print(stack<T> a) { while(!a.empty()) { cout<<a.top()<<'\t'; a.pop();//元素出棧 } } int main() { /*stack的操作*/ stack<int> s; for(int i=0;i<5;i++) { s.push(i);//元素進棧 } cout<<"s的大小為:"<<s.size()<<endl; cout<<"s為:\n"; print(s); cout<<endl; deque<int> d(5,7); stack<int> s1(d);//將deque賦值給stack cout<<"s1為:\n"; print(s1); cout<<endl; vector<string> v={"aa","ss","dd","ff"}; stack<string,vector<string> >s2(v);//將vector賦值給stack cout<<"s2為:\n"; while(!s2.empty()) { cout<<s2.top()<<'\t'; s2.pop();//元素出棧 } cout<<endl; list<char> c={'a','s','d','f','g','h'}; stack<char,list<char> > s3(c);//將list賦值給stack cout<<"s3為:\n"; while(!s3.empty()) { cout<<s3.top()<<'\t'; s3.pop();//元素出棧 } cout<<endl; return 0; }
隊列和棧的基本操作差不多

#include <iostream> #include <stdlib.h> #include <string.h> #include <algorithm> #include <queue> #include <deque> #include <vector> #include <list> using namespace std; //利用模版進行輸出 template <typename T> void print(queue<T> a) { while(!a.empty()) { cout<<a.front()<<'\t'; a.pop();//元素出棧 } } int main() { /*queue的操作*/ queue<int> s; for(int i=0;i<5;i++) { s.push(i);//元素進棧 } cout<<"s的大小為:"<<s.size()<<endl; print(s); cout<<endl; deque<int> d(5,7); queue<int> s1(d);//將deque賦值給stack cout<<"s1為:\n"; print(s1); cout<<endl; vector<string> v={"aa","ss","dd","ff","hh"}; queue<string,vector<string> >s2(v);//將vector賦值給stack cout<<s2.front()<<'\t'<<s2.back()<<endl; list<char> c={'a','s','d','f','g','h'}; queue<char,list<char> > s3(c);//將list賦值給stack cout<<"s3為:\n"; while(!s3.empty()) { cout<<s3.front()<<'\t'; s3.pop();//元素出棧 } cout<<endl; return 0; }
6、Map的基本使用
Map主要用於資料一對一映射(one-to-one)的情況,map內部的實現自建一顆紅黑樹,這顆樹具有對數據自動排序的功能。
begin() 返回指向map頭部的迭代器
clear() 刪除所有元素
count() 返回指定元素出現的次數
empty() 如果map為空則返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊條目的迭代器對
erase() 刪除一個元素
find() 查找一個元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比較元素key的函數
lower_bound() 返回鍵值>=給定元素的第一個位置
max_size() 返回可以容納的最大元素個數
rbegin() 返回一個指向map尾部的逆向迭代器
rend() 返回一個指向map頭部的逆向迭代器
size() 返回map中元素的個數
swap() 交換兩個map
upper_bound() 返回鍵值>給定元素的第一個位置
value_comp() 返回比較元素value的函數

#include <iostream> #include <stdlib.h> #include <string.h> #include <algorithm> #include <map> #include <deque> #include <vector> #include <list> using namespace std; //利用模版進行輸出 template <typename T> void print(map<T,T> a) { cout<<"輸出的方法1:\n"; typename map<T, T>::iterator it; for(it = a.begin(); it != a.end(); it++) cout<<it->first<<' '<<it->second<<endl; cout<<"輸出的方法2:\n"; typename map<T, T>::reverse_iterator iter; for(iter = a.rbegin(); iter != a.rend(); iter++) cout<<iter->first<<' '<<iter->second<<endl; } int main() { /*map的賦值操作*/ map<string, string> m; //賦值的方法1 m.insert(map<string, string>::value_type ("001", "s1")); m.insert(map<string, string>::value_type ("002", "s2")); m.insert(map<string, string>::value_type ("003", "s3")); //賦值方法2 m.insert(pair<string,string>("004","s4")); m.insert(pair<string,string>("005","s5")); m.insert(pair<string,string>("006","s6")); print(m); cout<<"--------------------------------------------"<<endl; map<int, string> m2; //賦值的方法3 m2[1]="one"; m2[2]="two"; m2[3]="three"; // print(m2); 這里兩個類型不一樣不能進行模版輸出 map<int, string>::iterator iter2; for(iter2 = m2.begin(); iter2 != m2.end(); iter2++) cout<<iter2->first<<' '<<iter2->second<<endl; for(int i=1;i<=3;i++)//這種輸出必須保證map中前一個數為int類型 { cout<<m2[i]<<endl; } cout<<"--------------------------------------------"<<endl; /*判斷插入是否成功*/ map<char,char> m3; m3.insert(map<char,char>::value_type('1','a')); m3.insert(map<char,char>::value_type('2','b')); m3.insert(map<char,char>::value_type('3','c')); m3.insert(map<char,char>::value_type('4','e')); m3.insert(map<char,char>::value_type('5','f')); m3.insert(map<char,char>::value_type('6','g')); pair<map<char,char>::iterator,bool> insert_pair;//接收判斷插入的成功與否 insert_pair=m3.insert(pair<char,char>('4','d')); if(insert_pair.second) cout<<"插入成功!"<<endl; else cout<<"插入失敗!"<<endl; insert_pair=m3.insert(pair<char,char>('4','d')); if(insert_pair.second) cout<<"插入成功!"<<endl; else cout<<"插入失敗!"<<endl; print(m3); cout<<"--------------------------------------------"<<endl; cout<<"m3的大小為:"<<m3.size()<<endl; cout<<"--------------------------------------------"<<endl; /*數據查找*/ //1 map<char,char>::iterator iter=m3.find('2'); if(iter!=m3.end()) cout<<"2對應的值為"<<iter->second<<endl; //2 int n=m3.count('2'); if(n) cout<<"2存在於map中"<<endl; else cout<<"2不存在於map中"<<endl; //3 iter=m3.lower_bound('2'); cout<<"2對應的值為:"<<iter->second<<endl; iter=m3.upper_bound('2'); cout<<"2后面的鍵對應的值為:"<<iter->second<<endl; cout<<"--------------------------------------------"<<endl; /*數據刪除*/ //1 iter=m3.find('2'); m3.erase(iter); //2 n=m3.erase('3'); if(n) cout<<"3以及對應的value刪除成功"<<endl; else cout<<"3以及對應的value刪除失敗"<<endl; //3 m3.erase(++m3.begin(),--m3.end()); print(m3); }
容器選擇的基本原則:
1、除非你有很多的理由選擇其它的容器,否則應該用vector。
2、如果你的程序有很多小的元素,且空間的額外開銷很重要,則不要使用list。
3、如果程序要求隨機訪問元素,則應該使用vector或則deque。
4、如果程序需要在容器的中間插入刪除元素,應該使用list。
5、如果程序需要在容器的頭尾位置插入或刪除元素,但不會在中間位置進行插入或者刪除操作,則使用deque。
6、如果程序只有在讀取輸入時才需要在容器中間位置插入元素,隨后需要隨機訪問元素則:
首先,確定是否真的需要在容器中間位置添加元素,當處理輸入數據時,通常可以很容易地向vector追加數據,然后調用標准庫的sort函數來重排容器中的元素,從而避免在中間位置添加元素。
如果必須在中間位置插入元素,考慮在輸入階段使用list,一旦輸入完成,將list中的內容拷貝到一個vector中。
注:如果不確定應該使用哪種容器,那么可以在程序中只使用vector和list公共的操作:使用迭代器,不使用下表操作,避免隨機訪問。這樣。在必要的時候選擇vector或list都很方便。