1、它是一種模板類型的結(jié)構(gòu)體,定義在頭文件#include<utility>
template<class T1,class T2>
2、有兩個(gè)成員是first,second
3、模板參數(shù)可以是任何類型的
1、分為序列式容器和關(guān)聯(lián)式容器
1)序列式容器就是里面操作的數(shù)據(jù)無關(guān)聯(lián),比如:vector,它的操作push,pop
2)關(guān)聯(lián)式容器就是里面操作的數(shù)據(jù)有關(guān)聯(lián),比如:set,map,它的操作insert,erase
*set是一種Key結(jié)構(gòu),它的元素就是它的鍵值,它的鍵值唯一,不允許重復(fù),它里面的數(shù)都會(huì)被自動(dòng)排序。
*它也是模板類型的:
template < class T,class Compare = less<T>, class Alloc = allocator<T> > class set;
1)第一個(gè)參數(shù)是鍵值類型
2)第二個(gè)模板參數(shù)可以利用仿函數(shù)實(shí)現(xiàn),這樣我們就可以控制在set中插入值的時(shí)候是按什么順序進(jìn)行排列的
3)第三個(gè)參數(shù)是空間配置器
1)插入到set中的值是排好序的
2)如果重復(fù)進(jìn)行插入的話,set是會(huì)把重復(fù)的值過濾掉的(防冗余)
它在底層是利用紅黑樹進(jìn)行實(shí)現(xiàn)的,但注意它的底層插入機(jī)制是insert_unique
三種類型:
A:直接插入一個(gè)值:pair<iterator,bool> insert ( const value_type& x );B:在特定的位置插入一個(gè)值:iterator insert ( iterator position, const value_type& x );C:插入一段區(qū)間:template <class InputIterator>void insert ( InputIterator first,InputIterator last);
用代碼簡(jiǎn)單使用:
void TestSet(){ //插入的測(cè)試 //1、直接插入一個(gè)值 set<int> s1; s1.insert(1); s1.insert(2); s1.insert(3); s1.insert(4); s1.insert(5); //2、在特定的位置進(jìn)行插入 /*s1.insert(s1.begin(),10); s1.insert(s1.begin(),5); s1.insert(s1.begin(),7); s1.insert(s1.begin(),9);*/ //3、插入一段區(qū)間 //s1.insert (s1.begin(),s1.end()); set<int>::iterator it1 = s1.begin(); while(it1 != s1.end()) { cout<<*it1<<" "; it1++; } cout<<endl;}2)erase
三種類型:
A:刪除特定位置的值:void erase ( iterator position );B:刪除一個(gè)值:size_type erase ( const key_type& x );C:刪除一段迭代器區(qū)間:void erase ( iterator first, iterator last );
用代碼簡(jiǎn)單使用:
void TestSet(){ //插入的測(cè)試 //1、直接插入一個(gè)值 set<int> s1; s1.insert(1); s1.insert(2); s1.insert(3); s1.insert(4); s1.insert(5); //2、在特定的位置進(jìn)行插入 /*s1.insert(s1.begin(),10); s1.insert(s1.begin(),5); s1.insert(s1.begin(),7); s1.insert(s1.begin(),9);*/ //3、插入一段區(qū)間 //s1.insert (s1.begin(),s1.end()); //刪除的測(cè)試 //1、直接刪除值 //說明:刪除這個(gè)值得時(shí)候,如果不在你原本的插入數(shù)據(jù)中時(shí),不會(huì)發(fā)生崩潰 /*s1.erase(4); s1.erase(1); s1.erase(6);*/ //2、刪除一個(gè)特定位置的值 //說明:如果是刪除一個(gè)位置上的數(shù)的話,如果沒有這個(gè)數(shù)的話,刪除的話 // 就會(huì)崩潰 //set<int>::iterator pos = s1.find(6); //s1.erase(pos); //3、刪除一段迭代器區(qū)間 //s1.erase(++s1.begin(),--s1.end()); set<int>::iterator it1 = s1.begin(); while(it1 != s1.end()) { cout<<*it1<<" "; it1++; } cout<<endl;}說明:要注意的點(diǎn)我在上面的測(cè)試代碼中已經(jīng)說明。3)count:
判斷一個(gè)值是否存在,存在的話返回1,不存在返回0
//如果要查找值是否存在,那么可以用find先進(jìn)行查找,然后再進(jìn)行 //判斷是否存在 map<string,int>::iterator it1 = countstr.find(1); if(it1 != countstr.end()) {} else {} //而如果用count的話,因?yàn)樗囊饬x。我們可以直接來進(jìn)行判斷 if(countstr.count(key) > 0) {} else {}4)emplace:
c++11新特性:
說明:用于插入一個(gè)元素,比insert的效率高一些, insert插入的時(shí)候返回是先進(jìn)行構(gòu)造一個(gè)臨時(shí)對(duì)象,然后通過這個(gè)臨時(shí)對(duì)象再進(jìn)行拷貝構(gòu)造,而emplace是直接就進(jìn)行的構(gòu)造,效率更高一些
簡(jiǎn)單使用:
set<string> s2; s2.emplace("hello"); auto ret = s2.emplate("hello"); if(!ret.second) cout<<"hello 已經(jīng)存在"<<endl;5)find:
iterator find(const value_type& val) const;
如果找到的話就返回這個(gè)位置的迭代器,否則就返回end。
6、應(yīng)用:
1)因?yàn)閟et里有檢查值是否存在的接口count,因此我們可以使用set來進(jìn)行單詞拼寫的檢查
2)插入的時(shí)候有防冗余的作用,可以用于過濾,我們可以用其實(shí)現(xiàn)爬蟲
二、map(映射)
1、概念:
*map是一種key(鍵值)-value(實(shí)值)結(jié)構(gòu);
它的每一種鍵值對(duì)應(yīng)它的實(shí)值。
它有鍵值和實(shí)值,它的鍵值是不允許更改的,但是它的實(shí)值是可以不同的。
map中的所有元素都是pair,pair的first被視為鍵值,它的second被視為實(shí)值。
(map的每個(gè)元素都是pair類型。typedef pair<K,V> value_type;)
*它也有和set類似的模板結(jié)構(gòu)
template<class Key,class T,classCompare=less<Key>,class Alloc=allocator<pair<const Key,T> > >它有四個(gè)模板參數(shù)類型,第一個(gè)是鍵值的類型。第二個(gè)是實(shí)值的類型。第三個(gè)是一個(gè)仿函數(shù),它傳入的是鍵值的比較方式,默認(rèn)是升序排列。第四個(gè)是空間配置器。
2、底層實(shí)現(xiàn):
也是通過紅黑樹進(jìn)行實(shí)現(xiàn)的
3、一些常用接口的簡(jiǎn)介
1)insert:
三種類型:
*pair<iterator,bool> insert(const value_type& val); 說明: 插入一個(gè)value_type類型,返回值是一個(gè)pair類型。 pair<iterator,bool>=pair<map<K,V>::iterator,bool>。如果插入成功的話則bool就為true,且iterator指向插入的位置,否則的話iterator就指向已經(jīng)存在的這個(gè)元素的位置。iterator是一個(gè)pair<K,V>類型的迭代器。 *iterator insert(iterator,const value_type& val) 在一個(gè)迭代器的位置插入一個(gè)value_type類型的數(shù)據(jù),如果插入成功的話返回這個(gè)成功位置的迭代器,如果失敗的話則返回這個(gè)傳入的迭代器。
*template<class InputIterator> void insert(InputIterator first,InputIterator last); 插入一段迭代器區(qū)間
2)erase:
*void erase(iterator position) 刪除一個(gè)這個(gè)迭代器位置的元素。 *size_type erase(const key_type& k) 刪除這個(gè)鍵值所在的位置,成功返回1,失敗返回0 *void erase(iterator first,iterator last); 刪除一段迭代器區(qū)間。
3)find:
iterator find(const key_type& k) 如果查找成功的話則返回這個(gè)元素的迭代器,否則返回end,所以在使用find返回的迭代器之前要先判斷一下。4)count:
size_type count(const key_type& k)const 與set的count功能一樣。
5)Operator[]
mapped_type& operator[](const key_type& k) map中的operator[]是最常用的,如果map中有這個(gè)k,則它就把這個(gè)k所對(duì)應(yīng)的value的引用返回。如果map中沒有這個(gè)k的話,則它會(huì)調(diào)用insert(pair<K,V>(k,V())),將k和V的缺省值對(duì)應(yīng)起來插入進(jìn)去,并返回這個(gè)value的引用。 模擬實(shí)現(xiàn)下重載下標(biāo)操作符:
V& operator[](const K& key) { pair<iterator,bool> ret = insert(const K& key,const V& value); return ret->first.second; }3、應(yīng)用:
1)通常用來實(shí)現(xiàn)字典結(jié)構(gòu)
2)統(tǒng)計(jì)字符串出現(xiàn)的個(gè)數(shù)等等
三、multiset和multimap簡(jiǎn)單說明
1、multiset:
1)接口和set類似
2)要說明的:
**multiset的插入是不防冗余的,插入的原則就是中序遍歷之后是有序即可
**multiset要是要查找一個(gè)重復(fù)插入的值的話,它找到的是這些重復(fù)數(shù)的第一個(gè)。
#include<iostream>//#include<multimap>#include<set>using namespace std;void TestMultimap(){ multiset<int> m2; m2.insert(1); m2.insert(2); m2.insert(3); m2.insert(2); m2.insert(5); multiset<int>::iterator it2 = m2.find(2); cout<<*it2<<endl; it2++; cout<<*it2<<endl; it2++;};int main(){ TestMultimap(); return 0;}2、multimap:
1)key可以相同,但是value可以不同,這是要和map進(jìn)行區(qū)別的一點(diǎn)
2)它沒有重載下標(biāo)運(yùn)算符[]
3)它里面的count是真正意義上的進(jìn)行統(tǒng)計(jì)個(gè)數(shù),因?yàn)樗彩遣环廊哂嗟?,而在set和map中,count其實(shí)就只是充當(dāng)找這個(gè)值是否存在。
四、一些要說的瑣碎之話:
1、關(guān)于空間適配器和容器的區(qū)別
適配器說白了就是用于轉(zhuǎn)換。我用下面的棧和map舉個(gè)例子來說明下:
1)stack和queue是適配器
2)map和set是容器

新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注