标准模板库(STL)学习指南之set集合
/*?聯合容器將值與關鍵字聯合在一起,使用關鍵字來查找值,
*?提供元素的快速訪問,插入元素不能指定位置,容器自動處理插入位置
*?STL?提供四種聯合容器:set、multiset、map、multimap
*?set、multiset?存儲一種元素,前者關鍵字不可重復,后者關鍵字可以重復。
*?map、multimap?存儲一對元素鍵與值,前者關鍵字不可重復,后者關鍵字可以重復。
*/
set?是關聯容器。其鍵值就是實值,實值就是鍵值,不可以有重復(如果需求要求是可重復的,則請使用multiset),所以我們不能通過set的迭代器來改變set的元素的值,set擁有和list相同的特性:當?對他進行插入和刪除操作的時候,操作之前的迭代器依然有效。當然刪除了的那個就沒效了。set的底層結構是RB-tree,所以是有序的。平衡二叉檢索樹的檢索使用中序遍歷算法,檢索效率高于vector、deque、和list的容器。另外,采用中序遍歷算法可將鍵值由小到大遍歷出來,所以,可以理解為平衡二叉檢索樹在插入元素時,就會自動將元素按鍵值從小到大的順序排列。
Set的特性:
1.stl中特別提供了一種針對set的操作的算法:交集set_intersection,并集set_union,差集set_difference,對稱差集set_symeetric_difference。
set模板類的聲明:
| template?< ???class?key ???class?=Traitsless<key>? ???class?Allocator=allocator<key> > class?set。 |
其中個參數的意義如下:
key:要放入set里的數據類型,可以是任何類型的數據。
Traits:這是一個仿函數(關于仿函數是什么,我后面的文章會講到)。提供?了具有比較功能的仿函數,來覺得元素在set里的排列的順序,這是一個可選的參數,默認的是std::less<key>,如果要自己提供這?個參數,那么必須要遵循此規則:具有兩個參數,返回類型為bool。
Allocator:空間配置器,這個參數是可選的,默認的是std::allocator<key>.
?
?
?
?
?
?
?
?
遍歷迭代器:
普通迭代器:
std::set<int>::iterator?it?=?s.begin();
while(it!=s.end())
{
???cout<<*it++<<endl;//迭代器依次后移,直到末尾。
}
反向迭代器:
std::set<int>::reverse_iterator?it?=?s.rbegin();
while(it!=s.rend())
{
cout<<*it++<<endl;
}
插入迭代器:
插入迭代器(Insert?Iterator),又叫插入器(Inserter),是繼上次的反向迭代器之后C++中的又一個迭代器適配器。插入迭代器的主要功能為把一個賦值操作轉?換為把相應的值插入容器的操作。插入迭代器對標準算法庫而言尤其重要。算法庫對所有在容器上的操作有個承諾:決不修改容器的大小(不插入、不刪除)。有了?插入迭代器,既使得算法庫可以通過迭代器對容器插入新的元素,又不違反這一承諾,即保持了設計上的一致性。
???????插入迭代器提供了以下幾種操作:*itr,itr++,++itr,itr?=?value。但實際上,前三種操作為“空操作”(no-op),僅僅返回itr。第四種操作itr?=?value才是插入迭代器的核心,這個操作通過調用容器的成員函數(push_back(),push_front(),insert(),取決于插入器?類型)把value插入到插入器對應容器的相應的位置上。
???????插入迭代器分為三種類型:尾部插入器(back_insert_iterator),首部插入器(front_insert_iterator)和普通插?入器(insert_iterator)。第一種通過調用容器的push_back成員函數來插入元素,因此這種插入器只對?vector,list,deque和string有效。?第二種通過調用容器的push_front成員函數來插入元素,因此它只對list和deque有效。第三種通過調用insert成員函數來插入元素,并?由用戶指定插入位置,它對所有標準的容器類型都有效,因為所有容器都定義了insert成員函數。
ostream_iterator
ostream_iterator屬于I/O流STL適配器
?
?
自定義比較函數
?????????使用insert將元素插入到集合中去的時候,集合會根據設定的比較函數獎該元素放到該放的節點上去。在定義集合的時候,如果沒有指定比較函數,那么采用默認的比較函數,即按鍵值從小到大的順序插入元素。但在很多情況下,需要自己編寫比較函數。
編寫比較函數有兩種方法。
(1)如果元素不是結構體,那么可以編寫比較函數。下面的程序比較規則為按鍵值從大到小的順序插入到集合中。
#include?"stdafx.h"
#include<iostream>
#include<set>
using?namespace?std;
struct?mycomp
{?
//自定義比較函數,重載“()”操作符??
bool?operator()?(const?int?&a,?const?int?&b)??
{??
if(a?!=?b)??
return?a?>?b;??
else??
return?a?>?b;??
}??
};??
int?main()??
{??
set<int,?mycomp>?s;?//采用比較函數mycomp??
s.insert(5);?//第一次插入,可以插入??
s.insert(1);??
s.insert(6);??
s.insert(3);??
s.insert(5);?//第二次插入,重復元素,不會插入??
set<int,mycomp>::iterator?it;
for(it?=?s.begin();?it?!=?s.end();?it++)
cout?<<*it<<"?";
cout?<<?endl;
return?0;??
}??
?
?
?
?
(2)如果元素是結構體,那么可以直接把比較函數寫在結構體內。?
?
#include?"stdafx.h"
#include<iostream>
#include<set>
using?namespace?std;
struct?mycomp
{?
//自定義比較函數,重載“()”操作符??
bool?operator()?(const?int?&a,?const?int?&b)??
{??
if(a?!=?b)??
return?a?>?b;??
else??
return?a?>?b;??
}??
};??
int?main()??
{??
set<int,?mycomp>?s;?//采用比較函數mycomp??
s.insert(5);?//第一次插入,可以插入??
s.insert(1);??
s.insert(6);??
s.insert(3);??
s.insert(5);?//第二次插入,重復元素,不會插入??
set<int,mycomp>::iterator?it;
for(it?=?s.begin();?it?!=?s.end();?it++)
cout?<<*it<<"?";
cout?<<?endl;
return?0;??
}??
總結
以上是生活随笔為你收集整理的标准模板库(STL)学习指南之set集合的全部內容,希望文章能夠幫你解決所遇到的問題。