1. 程式人生 > >STL之Set:Set的基本用法

STL之Set:Set的基本用法

set集合容器實現了紅黑樹(Red-Black Tree)的平衡二叉檢索樹的的資料結構,在插入元素時,它會自動調整二叉樹的排列,把該元素放到適當的位置,以確保每個子樹根節點的鍵值大於左子樹所有節點的鍵值,而小於右子樹所有節點的鍵值;另外,還得確保根節點的左子樹的高度與有字數的高度相等,這樣,二叉樹的高度最小,從而檢索速度最快。要注意的是,它不會重複插入相同鍵值的元素,而採取忽略處理。

        平衡二叉檢索樹的檢索使用中序遍歷演算法,檢索效率高於vector、deque、和list的容器。另外,採用中序遍歷演算法可將鍵值由小到大遍歷出來,所以,可以理解為平衡二叉檢索樹在插入元素時,就會自動將元素按鍵值從小到大的順序排列。

Set容器和其他容器差不多,無非就是相同的值不存,存進去自動排序好了。

        構造set集合的主要目的是為了快速檢索,使用set前,需要在程式標頭檔案中包含宣告“#include<set>”。

1.建立set集合物件

           建立set物件時,需要指定元素的型別,這一點和其他容器一樣。

  1. #include<iostream>
  2. #include<set>
  3. usingnamespace std;  
  4. int main()  
  5. {  
  6.     set<int> s;  
  7.     return 0;  
  8. }  
2.元素的插入與中序遍歷

        採用inset()方法把元素插入到集合中,插入規則在預設的比較規則下,是按元素值從小到大插入,如果自己指定了比較規則函式,則按自定義比較規則函式插入。使用前向迭代器對集合中序遍歷,結果正好是元素排序後的結果。

  1. #include<iostream>
  2. #include<set>
  3. usingnamespace std;  
  4. int main()  
  5. {  
  6.     set<int> s;  
  7.     s.insert(5); //第一次插入5,可以插入
  8.     s.insert(1);  
  9.     s.insert(6);  
  10.     s.insert(3);  
  11.     s.insert(5); //第二次插入5,重複元素,不會插入
  12.     set<int>::iterator it; //定義前向迭代器
  13.     //中序遍歷集合中的所有元素
  14.     for(it = s.begin(); it != s.end(); it++)  
  15.     {  
  16.         cout << *it << " ";  
  17.     }  
  18.     cout << endl;  
  19.     return 0;  
  20. }  
  21. //執行結果:1 3 5 6
3.元素的方向遍歷

        使用反向迭代器reverse_iterator可以反向遍歷集合,輸出的結果正好是集合元素的反向排序結果。它需要用到rbegin()和rend()兩個方法,它們分別給出了反向遍歷的開始位置和結束位置。

  1. #include<iostream>
  2. #include<set>
  3. usingnamespace std;  
  4. int main()  
  5. {  
  6.     set<int> s;  
  7.     s.insert(5); //第一次插入5,可以插入
  8.     s.insert(1);  
  9.     s.insert(6);  
  10.     s.insert(3);  
  11.     s.insert(5); //第二次插入5,重複元素,不會插入
  12.     set<int>::reverse_iterator rit; //定義反向迭代器
  13.     //反向遍歷集合中的所有元素
  14.     for(rit = s.rbegin(); rit != s.rend(); rit++)  
  15.     {  
  16.         cout << *rit << " ";  
  17.     }  
  18.     cout << endl;  
  19.     return 0;  
  20. }  
  21. //執行結果:6 5 3 1
4.元素的刪除

        與插入元素的處理一樣,集合具有高效的刪除處理功能,並自動重新調整內部的紅黑樹的平衡。刪除的物件可以是某個迭代器位置上的元素、等於某鍵值的元素、一個區間上的元素和清空集合。

  1. #include<iostream>
  2. #include<set>
  3. usingnamespace std;  
  4. int main()  
  5. {  
  6.     set<int> s;  
  7.     s.insert(5); //第一次插入5,可以插入
  8.     s.insert(1);  
  9.     s.insert(6);  
  10.     s.insert(3);  
  11.     s.insert(5); //第二次插入5,重複元素,不會插入
  12.     s.erase(6); //刪除鍵值為6的元素
  13.     set<int>::reverse_iterator rit; //定義反向迭代器
  14.     //反向遍歷集合中的所有元素
  15.     for(rit = s.rbegin(); rit != s.rend(); rit++)  
  16.     {  
  17.         cout << *rit << " ";  
  18.     }  
  19.     cout << endl;   
  20.     set<int>::iterator it;  
  21.     it = s.begin();  
  22.     for(int i = 0; i < 2; i++)  
  23.         it = s.erase(it);   
  24.     for(it = s.begin(); it != s.end(); it++)  
  25.         cout << *it << " ";  
  26.     cout << endl;  
  27.     s.clear();  
  28.     cout << s.size() << endl;  
  29.     return 0;  
  30. }  
  31. /* 
  32. 執行結果: 
  33. 5 3 1 
  34. 5 
  35. 0     
  36. */
5.元素的檢索

          使用find()方法對集合進行檢索,如果找到查詢的的鍵值,則返回該鍵值的迭代器位置;否則,返回集合最後一個元素後面的一個位置,即end()。

  1. #include<iostream>
  2. #include<set>
  3. usingnamespace std;  
  4. int main()  
  5. {  
  6.     set<int> s;  
  7.     s.insert(5); //第一次插入5,可以插入
  8.     s.insert(1);  
  9.     s.insert(6);  
  10.     s.insert(3);  
  11.     s.insert(5); //第二次插入5,重複元素,不會插入
  12.     set<int>::iterator it;  
  13.     it = s.find(6); //查詢鍵值為6的元素
  14.     if(it != s.end())  
  15.         cout << *it << endl;  
  16.     else
  17.         cout << "not find it" << endl;  
  18.     it = s.find(20);  
  19.     if(it != s.end())  
  20.         cout << *it << endl;  
  21.     else
  22.         cout << "not find it" << endl;  
  23.     return 0;  
  24. }  
  25. /* 
  26. 執行結果: 
  27. 6 
  28. not find it    
  29. */

下面這種方法也能判斷一個數是否在集合中:

  1. #include <cstdio>
  2. #include <set>
  3. usingnamespace std;  
  4. int main() {  
  5.     set <int> s;  
  6.     int a;  
  7.     for(int i = 0; i < 10; i++)  
  8.         s.insert(i);  
  9.     for(int i = 0; i < 5; i++) {  
  10.         scanf("%d", &a);  
  11.         if(!s.count(a)) //不存在
  12.             printf("does not exist\n");  
  13.         else
  14.             printf("exist\n");  
  15.     }  
  16.     return 0;  
  17. }  

6.自定義比較函式

         使用insert將元素插入到集合中去的時候,集合會根據設定的比較函式獎該元素放到該放的節點上去。在定義集合的時候,如果沒有指定比較函式,那麼採用預設的比較函式,即按鍵值從小到大的順序插入元素。但在很多情況下,需要自己編寫比較函式。

編寫比較函式有兩種方法。

(1)如果元素不是結構體,那麼可以編寫比較函式。下面的程式比較規則為按鍵值從大到小的順序插入到集合中。

  1. #include<iostream>
  2. #include<set>
  3. usingnamespace std;  
  4. struct mycomp  
  5. //自定義比較函式,過載“()”操作符
  6.     bool operator() (constint &a, constint &b)  
  7.     {  
  8.         if(a != b)  
  9.             return a > b;  
  10.         else
  11.             return a > b;  
  12.     }  
  13. };  
  14. int main()  
  15. {  
  16.     set<int, mycomp> s; //採用比較函式mycomp
  17.     s.insert(5); //第一次插入5,可以插入
  18.     s.insert(1);  
  19.     s.insert(6);  
  20.     s.insert(3);  
  21.     s.insert(5); //第二次插入5,重複元素,不會插入
  22.     set<int,mycomp>::iterator it;  
  23.     for(it = s.begin(); it != s.end(); it++)  
  24.         cout << *it << " ";  
  25.     cout << endl;  
  26.     return 0;  
  27. }  
  28. /* 
  29. 執行結果:6 5 3 1   
  30. */
(2)如果元素是結構體,那麼可以直接把比較函式寫在結構體內。
  1. #include<iostream>
  2. #include<set>
  3. #include<string>
  4. usingnamespace std;  
  5. struct Info  
  6. {  
  7.     string name;  
  8.     double score;  
  9.     bool operator < (const Info &a) const// 過載“<”操作符,自定義排序規則
  10.     {  
  11.         //按score由大到小排序。如果要由小到大排序,使用“>”即可。
  12.         return a.score < score;  
  13.     }  
  14. };  
  15. int main()  
  16. {  
  17.     set<Info> s;  
  18.     Info info;  
  19.     //插入三個元素
  20.     info.name = "Jack";  
  21.     info.score = 80;  
  22.     s.insert(info);  
  23.     info.name = "Tom";  
  24.     info.score = 99;  
  25.     s.insert(info);  
  26.     info.name = "Steaven";  
  27.     info.score = 60;  
  28.     s.insert(info);  
  29.     set<Info>::iterator it;  
  30.     for(it = s.begin(); it != s.end(); it++)  
  31.         cout << (*it).name << " : " << (*it).score << endl;   
  32.     return 0;  
  33. }  
  34. /* 
  35. 執行結果: 
  36. Tom : 99 
  37. Jack : 80 
  38. Steaven : 60 
  39. */

Set常用函式:跟其他容器的函式差不多,好像都通用

c++ stl容器set成員函式:begin()--返回指向第一個元素的迭代器

c++ stl容器set成員函式:clear()--清除所有元素

c++ stl容器set成員函式:count()--返回某個值元素的個數

c++ stl容器set成員函式:empty()--如果集合為空,返回true

c++ stl容器set成員函式:end()--返回指向最後一個元素的迭代器

c++ stl容器set成員函式:equal_range()--返回集合中與給定值相等的上下限的兩個迭代器

c++ stl容器set成員函式:erase()--刪除集合中的元素

c++ stl容器set成員函式:find()--返回一個指向被查詢到元素的迭代器

c++ stl容器set成員函式:get_allocator()--返回集合的分配器

c++ stl容器set成員函式:insert()--在集合中插入元素

c++ stl容器set成員函式:lower_bound()--返回指向大於(或等於)某值的第一個元素的迭代器

c++ stl容器set成員函式:key_comp()--返回一個用於元素間值比較的函式

c++ stl容器set成員函式:max_size()--返回集合能容納的元素的最大限值

c++ stl容器set成員函式:rbegin()--返回指向集合中最後一個元素的反向迭代器

c++ stl容器set成員函式:rend()--返回指向集合中第一個元素的反向迭代器

c++ stl容器set成員函式:size()--集合中元素的數目

c++ stl容器set成員函式:swap()--交換兩個集合變數

c++ stl容器set成員函式:upper_bound()--返回大於某個值元素的迭代器

c++ stl容器set成員函式:value_comp()--返回一個用於比較元素間的值的函式

相關推薦

STLvector容器用法詳解

// vectorsample.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include<iostream> #include<vector> #include<string> using namespace std; c

STLSetSet基本用法

set集合容器實現了紅黑樹(Red-Black Tree)的平衡二叉檢索樹的的資料結構,在插入元素時,它會自動調整二叉樹的排列,把該元素放到適當的位置,以確保每個子樹根節點的鍵值大於左子樹所有節點的鍵值,而小於右子樹所有節點的鍵值;另外,還得確保根節點的左子樹的高度與有字數

list,map,set集合的基本用法及差異

nbsp htable body 根據 pos null clas 速度 就是 List:1.可以允許重復的對象。    2.可以插入多個null元素。 3.是一個有序容器,保持了每個元素的插入順序,輸出的順序就是插入的順序。 4.常用的實

知識點Mysql 基本用法函數

select查詢 bar 基本用法 for lower www 順序 test ber 函數 MySQL中提供了許多內置函數 例如: sql 內置函數: 一、數學函數 ROUND(x,y) 返回參數x的四舍五入的有y位小數的值

知識點Mysql 基本用法存儲過程

rollback word tar for from iam tin ack -- 存儲過程 一、 介紹 存儲過程包含了一系列可執行的sql語句,存儲過程存放於MySQL中,通過調用它的名字可以執行其內部的一堆sql 使用存儲過程的優點: 用於替代程序寫的SQL語句,實

SPOJ ADAFIELD Ada and Field(STL的使用set,multiset,map的叠代器)題解

tdi 重復 pan eat iterator %d seed class ... 題意:n*m的方格,“0 x”表示x軸在x位置切一刀,“0 y”表示y軸在y位置切一刀,每次操作後輸出當前面積最大矩形。 思路:用set分別儲存x軸y軸分割的點,用multiset(可重復)

STLdeque用法詳解

deque函式: deque容器為一個給定型別的元素進行線性處理,像向量一樣,它能夠快速地隨機訪問任一個元素,並且能夠高效地插入和刪除容器的尾部元素。但它又與vector不同,deque支援高效插入和刪除容器的頭部元素,因此也叫做雙端佇列。deque類常用的函式如下。

python實戰筆記(13)Scrapy基本用法例項講解

Scrapy是一個非常強大的非同步爬蟲框架,它已經給我們寫好了許許多多的元件,使用Scrapy我們只用關心爬蟲的邏輯就好了。本文通過一個簡單的專案瞭解一下Scrapy的爬取流程,對Scrapy的基本用法也有一個大體的瞭解。 一、目標站點分析 Scrapy提供了一個官方抓取

一站式學習Wireshark(一)Wireshark基本用法

11g 實現 alt href ascii 根據 無線網絡 完成 analyze 按照國際慣例,從最基本的說起。 抓取報文: 下載和安裝好Wireshark之後,啟動Wireshark並且在接口列表中選擇接口名,然後開始在此接口上抓包。例如,如果想要在無線網絡上抓取流量

黃聰ffmpeg基本用法(轉)

sca wid cal ner aspect mp4 動態文本 tegra 控制輸出 FFmpeg FFmpeg 基本用法 本課要解決的問題 1.FFmpeg的轉碼流程是什麽? 2.常見的視頻格式包含哪些內容嗎? 3.如何把這些內容從視頻文件中抽取出來? 4.如

《Java從入門到放棄》入門篇springMVC基本用法

java springmvc springMVC可以理解成用來做數據顯示處理的框架,主要內容就是控制器和視圖的處理。在已經安裝了spring框架的基礎上繼續下面的步驟(我使用的MyEclipse2014)。 1. 修改web.xml文件 2. 在WEB-INF目錄創建springmvc的配

Labview入門認識基本控件

四種 定義 加粗 輸入 面板 操作 設置 http 重新 上一節簡單的介紹了如何新建一個簡單的VI,從中我們可以看到前面板上都是由控件選板上的控件添加的,這一節將會介紹這些基本的控件。打開控件選板(鼠標右鍵點擊前面板的空白處或者“查看”->"控件選板")。 1 數值控

linux學習2.基本指令(2)

inux 可執行文件 選項 說明 獨立 選項說明 img color 配置 一、在線求助:man page 與info page 1.man(manual:操作說明) page 我想查看日歷,所以我輸入man cal 效果如圖: 圖中CAL(1)中,在不同的指令中數字的含

Spring 基礎教程JavaBean基本配置詳解

一:xml 裝配JavaBean屬性含義: 1.id:指定該Bean 的唯一標識。 2.class:指定該Bean 的全限定名。 3.name:為該Bean 指定一到多個別名。多個別名可以用“,”和“;”分割。

06 awk基本用法 awk高階應用 總結和答疑

Top NSD SHELL DAY06 案例1:使用awk提取文字 案例2:awk處理條件 案例3:awk綜合指令碼應用 案例4:awk流程控制 案例5:awk擴充套件應用 1 案例1:使用awk提取文字 1.1 問題 本案例要求使用awk

Elasticsearch入門三Elasticsearch基本用法-增刪改查(譯)

title: Elasticsearch入門三:Elasticsearch基本用法-增刪改查(譯) date: 2018-11-01 11:00:00 tags: Elasticsearch 原文地址: https://www.elastic.co/guide/en/elast

Docker學習Docker基本簡單操作命令

查詢tomcat映象; docker search tomcat 進入容器 docker exec -it 458(容器ID) /bin/bash 檢視容器完整id docker inspect 14b7 | grep Id 上傳war包到docker docker te

C++STLVector向量詳解,用法和例子 一起學習 一起加油

                                            &

djangoORM介紹與基本用法(一)

  一、ORM介紹 1.什麼是ORM ORM 全拼Object-Relation Mapping. 中文意為 物件-關係對映. 在MVC/MVT設計模式中的Model模組中都包括ORM 2.ORM優勢 (1)只需要面

GitHub使用入門(二)Git基本用法

GitHub中的主要命令和用法都是在Git中完成的,所以我們有必要了解Git的基本語法和規則。下面來介紹一下: 基本操作 git init:初始化倉庫 必須先要進行初始化倉庫才能進行版本控制,下面我們就來實際進行初始化倉庫。 $ mkdir git-tut