1. 程式人生 > >set&& 用法整理

set&& 用法整理

set集合容器:實現了紅黑樹的平衡二叉檢索樹的資料結構,插入元素時,它會自動調整二叉樹的排列,把元素放到適當的位置,以保證每個子樹根節點鍵值大於左子樹所有節點的鍵值,小於右子樹所有節點的鍵值;另外,還得保證根節點左子樹的高度與右子樹高度相等。
平衡二叉檢索樹使用中序遍歷演算法,檢索效率高於vector、deque和list等容器,另外使用中序遍歷可將鍵值按照從小到大遍歷出來。
構造set集合主要目的是為了快速檢索,不可直接去修改鍵值。

常用操作:
1.元素插入:insert()
2.中序遍歷:類似vector遍歷(用迭代器)
3.反向遍歷:利用反向迭代器reverse_iterator。
    例:
    set<int> s;

    ......
    set<int>::reverse_iterator rit;
    for(rit=s.rbegin();rit!=s.rend();rit++)
4.元素刪除:與插入一樣,可以高效的刪除,並自動調整使紅黑樹平衡。
            set<int> s;
            s.erase(2);        //刪除鍵值為2的元素
            s.clear();
5.元素檢索:find(),若找到,返回該鍵值迭代器的位置,否則,返回最後一個元素後面一個位置。
            set<int> s;
            set<int>::iterator it;

            it=s.find(5);    //查詢鍵值為5的元素
            if(it!=s.end())    //找到
                cout<<*it<<endl;
            else            //未找到
                cout<<"未找到";
6.自定義比較函式
    (1)元素不是結構體:
        例:
        //自定義比較函式myComp,過載“()”操作符
        struct myComp
        {
            bool operator()(const your_type &a,const your_type &b)

            [
                return a.data-b.data>0;
            }
        }
        set<int,myComp>s;
        ......
        set<int,myComp>::iterator it;
    (2)如果元素是結構體,可以直接將比較函式寫在結構體內。
        例:
        struct Info
        {
            string name;
            float score;
            //過載“<”操作符,自定義排序規則
            bool operator < (const Info &a) const
            {
                //按score從大到小排列
                return a.score<score;
            }
        }
        set<Info> s;
        ......

        set<Info>::iterator it;

*******************************************************************************************************************

set是STL中一種標準關聯容器(vector,list,string,deque都是序列容器,而set,multiset,map,multimap是標準關聯容器),它底層使用平衡的搜尋樹——紅黑樹實現,插入刪除操作時僅僅需要指標操作節點即可完成,不涉及到記憶體移動和拷貝,所以效率比較高。set,顧名思義是“集合”的意思,在set中元素都是唯一的,而且預設情況下會對元素自動進行升序排列,支援集合的交(set_intersection),差(set_difference) 並(set_union),對稱差(set_symmetric_difference) 等一些集合上的操作,如果需要集合中的元素允許重複那麼可以使用multiset
#include<set>
#include<iterator>
#include<iostream>
using namespace std;
int main()
{
set<int>eg1;
//插入
eg1.insert(1);
eg1.insert(100);
eg1.insert(5);
eg1.insert(1);//元素1因為已經存在所以set中不會再次插入1
eg1.insert(10);
eg1.insert(9);
//遍歷set,可以發現元素是有序的
set<int>::iterator set_iter=eg1.begin();
cout<<"Set named eg1:"<<endl;
for(;set_iter!=eg1.end();set_iter++) cout<<*set_iter<<" ";
cout<<endl;
//使用size()函式可以獲得當前元素個數
cout<<"Now there are "<<eg1.size()<<" elements in the set eg1"<<endl;
if(eg1.find(200)==eg1.end())//find()函式可以查詢元素是否存在
   cout<<"200 isn't in the set eg1"<<endl;

set<int>eg2;
for(int i=6;i<15;i++)
eg2.insert(i);
cout<<"Set named eg2:"<<endl;
for(set_iter=eg2.begin();set_iter!=eg2.end();set_iter++)
   cout<<*set_iter<<" ";
cout<<endl;
//獲得兩個set的並
set<int>eg3;
cout<<"Union:";
set_union(eg1.begin(),eg1.end(),eg2.begin(),eg2.end(),insert_iterator<set<int> >(eg3,eg3.begin()));//注意第五個引數的形式
copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));
cout<<endl;
//獲得兩個set的交,注意進行集合操作之前接收結果的set要呼叫clear()函式清空一下
eg3.clear();
set_intersection(eg1.begin(),eg1.end(),eg2.begin(),eg2.end(),insert_iterator<set<int> >(eg3,eg3.begin()));
cout<<"Intersection:";
copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));
cout<<endl;
//獲得兩個set的差
eg3.clear();
set_difference(eg1.begin(),eg1.end(),eg2.begin(),eg2.end(),insert_iterator<set<int> >(eg3,eg3.begin()));
cout<<"Difference:";
copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));
cout<<endl;
//獲得兩個set的對稱差,也就是假設兩個集合分別為A和B那麼對稱差為AUB-A∩B
   eg3.clear();
   set_symmetric_difference(eg1.begin(),eg1.end(),eg2.begin(),eg2.end(),insert_iterator<set<int> >(eg3,eg3.begin()));
   copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));
   cout<<endl;

return 0;
}

set會對元素進行排序,那麼問題也就出現了排序的規則是怎樣的呢?上面的示例程式碼我們發現對int型的元素可以自動判斷大小順序,但是對char*就不會自動用strcmp進行判斷了,更別說是使用者自定義的型別了,事實上set的標準形式是set<Key, Compare, Alloc>,

引數 描述 預設值
Key 集合的關鍵字和值的型別
Compare 關鍵字比較函式,它的引數型別key引數指定的型別,如果第一個引數小於第二個引數則返回true,否則返回false less<Key>
Alloc set的分配器,用於內部記憶體管理 alloc

下面給出一個關鍵字型別為char*的示例程式碼

#include<iostream>
#include<iterator>
#include<set>
using namespace std;
struct ltstr
{
bool operator() (const char* s1, const char* s2) const
{
   return strcmp(s1, s2) < 0;
}
};

int main()
{
const int N = 6;
const char* a[N] = {"isomer", "ephemeral", "prosaic", 
   "nugatory", "artichoke", "serif"};
const char* b[N] = {"flat", "this", "artichoke",
   "frigate", "prosaic", "isomer"};

set<const char*,ltstr> A(a, a + N);
set<const char*,ltstr> B(b, b + N);
set<const char*,ltstr> C;

cout << "Set A: ";
//copy(A.begin(), A.end(), ostream_iterator<const char*>(cout, " "));
set<const char*,ltstr>::iterator itr;
for(itr=A.begin();itr!=A.end();itr++) cout<<*itr<<" ";
cout << endl;
cout << "Set B: ";
copy(B.begin(), B.end(), ostream_iterator<const char*>(cout, " "));   
cout << endl;

cout << "Union: ";
set_union(A.begin(), A.end(), B.begin(), B.end(),
    ostream_iterator<const char*>(cout, " "),
    ltstr());   
cout << endl;

cout << "Intersection: ";
set_intersection(A.begin(), A.end(), B.begin(),B.end(),ostream_iterator<const char*>(cout," "),ltstr());
cout<<endl;
set_difference(A.begin(), A.end(), B.begin(), B.end(),inserter(C, C.begin()),ltstr());
cout << "Set C (difference of A and B): ";
copy(C.begin(), C.end(), ostream_iterator<const char*>(cout, " "));
cout <<endl;
return 0;
}

其中的ltstr也可以這樣定義
class ltstr
{
        public:
        bool operator() (const char* s1,const char*s2)const
        {
                return strcmp(s1,s2)<0;
        }
};

更加通用的應用方式那就是資料型別也是由使用者自定義的類來替代,比較的函式自定義,甚至可以加上二級比較,比如首先按照總分數排序,對於分數相同的按照id排序,下面是示例程式碼

#include<set>
#include<iostream>
using namespace std;
struct
{
                int id;
                int score;
                string name;
};
struct compare
{
        bool operator()(const Entity& e1,const Entity& e2)const   {
                if(e1.score<e2.score) return true;
                else
                        if(e1.score==e2.score)
                                if(e1.id<e2.id) return true;

                return false;
        }
};

int main()
{
        set<Entity,compare>s_test;
        Entity a,b,c;
        a.id=123;a.score=90;a.name="bill";
        b.id=121;b.score=85;b.name="mary";
        c.id=130;c.score=85;c.name="jerry";
        s_test.insert(a);s_test.insert(b);s_test.insert(c);
        set<Entity,compare>::iterator itr;
        cout<<"Score List(ordered by score):\n";
        for(itr=s_test.begin();itr!=s_test.end();itr++)
                cout<<itr->id<<"---"<<itr->name<<"---"<<itr->score<<endl;
        return 0;
}


相關推薦

set&& 用法整理

set集合容器:實現了紅黑樹的平衡二叉檢索樹的資料結構,插入元素時,它會自動調整二叉樹的排列,把元素放到適當的位置,以保證每個子樹根節點鍵值大於左子樹所有節點的鍵值,小於右子樹所有節點的鍵值;另外,還得保證根節點左子樹的高度與右子樹高度相等。平衡二叉檢索樹使用中序遍歷演算法

C++ set用法總結(整理

順序容器包括vector、deque、list、forward_list、array、string,所有順序容器都提供了快速順序訪問元素的能力。 關聯容器包括set、map 關聯容器和順序容器有著根本的不同:關聯容器中的元素是按關鍵字來儲存和訪問的。與之相對,順序容器

Java中Iterator用法整理

mil rem println 對象 獲得 返回 new ext 插入 叠代器(Iterator)   叠代器是一種設計模式,它是一個對象,它可以遍歷並選擇序列中的對象,而開發人員不需要了解該序列的底層結構。叠代器通常被稱為“輕量級”對象,因為創建它的代價小。   Java

Java中vector用法整理

遍歷 檢索 集合 ash ets toa java code lan ArrayList會比Vector快,他是非同步的,如果設計涉及到多線程,還是用Vector比較好一些 import java.util.*; /** * 演示Vector的使用。包括Vector的創

find命令用法整理

find命令find命令 可以定位文件,配合參數可以快速定位所要找的文件使用方法:find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]常用的幾個[expression]

dos中定義變量與獲取常見的引用變量以及四則運算(set用法)

邏輯或 dos 擴展 use mysql\ gpo 當前 直接 var 在dos中使用set定義變量: set a=8 (註意等號兩邊沒有空格) 引用變量如: echo %a% 將打印a的值  (%a%是獲取變量a的值)

P1382 樓房 set用法小結

+= 離散化 小時 r+ include www ont urn RR 這個sb題目,劇毒。。。 STL大法好 首先,我準備用經典的線段樹優化掃描線來做。之前的矩形周長把我困了數天導致我胸有成竹。 然後,敲代碼半小時,調試半個月......這個,sb,怎麽改都是0分+2個R

vuex - 常用命令學習及用法整理

UNC 實例 tab justify 用法 變更 fun -c method https://vuex.vuejs.org/zh-cn/api.html 命令 用途 備註 this.$store 組件中訪問store實例 stor

ArrayList用法整理

osi 等於 AC index new DC void 內容 數組 System.Collections.ArrayList類是一個特殊的數組。通過添加和刪除元素,就可以動態改變數組的長度。 一.優點 1、支持自動改變大小的功能 2、可以靈活的插入元素 3、可以靈活的刪

C++STL庫常騰訊分用分彩平臺出租數據結構用法整理

隊列 splice 插入元素 key alloc ase 輸出 整理 eve vector騰訊分用分彩平臺出租 haozbbs.com Q1446595067創建對象,vector<int> vec;尾部插入數字,vec.push_back(a);使用下表訪

malloc用法整理

color 用戶 指針 signed 參考 void 12個 導致 數據 函數原型:void *malloc(unsigned int num_bytes);  //分配長度為num_bytes字節的內存塊  返回值是void指針,void* 表示未確定類型的指針,void

STL:set用法總結

i++ sset strcpy code con ++ per 開始 turn 一:介紹 set是STL的關聯式容器,以紅黑樹(Red-Black Tree)作為底層數據結構。自動去重,保證每個元素唯一,並對數據進行排序。 命名空間為std,所屬頭文件為<set>

const限定符用法整理

(1)const的來由    定義一種變數,我們希望防止程式不小心改變變數的值。因此產生了const限定符。 (2)初始化    由於const物件一旦建立就不可以改變,所以const物件必須進行初始化;    只能在c

C++ List的用法(整理)

Lists將元素按順序儲存在連結串列中. 與 向量(vectors)相比, 它允許快速的插入和刪除,但是隨機訪問卻比較慢. assign() 給list賦值  back() 返回最後一個元素  begin() 返回指向第一個元素的迭代器  clear() 刪除所有

linux學習:CURL用法整理

語法: curl [option] [url] 常用引數:-A/--user-agent <string> 設定使用者代理髮送給伺服器-b/--cookie <name=string/file> cookie字串或檔案讀取位置-c/--cookie-jar <file>

c++ const修飾符用法整理

1、什麼是const? 常型別是指使用型別修飾符const說明的型別,常型別的變數或物件的值是不能被更新的。(當然,我們可以偷樑換柱進行更新:) 修改常量:加mutable mutable class A { public: A(int i=0):test(i) { }

python set() 用法

set() 函式是python內建函式的其中一個,屬於比較基礎的函式。建立一個無序不重複元素集,可進行關係測試,刪除重複資料,還可以計算交集、差集、並集等。 class set([iterable]) 引數說明: iterable -- 可迭代物件物件; 返回新的集

[golang]golang reflect詳細用法整理

本部落格原創博文版權所有 @[email protected] 僅供交流學習使用用於商業用途請聯絡原作者  轉載請註明出處:http://blog.sina.com.cn/ally2014

java中json用法整理

阿里家的json 日常開發中遇到各種json,感覺用的比較亂,在這裡先著重整理一下阿里家的json用法。 Step1:maven配置 <dependency> <groupId>com.alibaba</groupId>

Python中xlrd常用用法整理

1.背景 1.1 安裝模板: 到python官網下載http://pypi.python.org/pypi/xlrd模組安裝,前提是已經安裝了python 環境。 在cmd命令列輸入:pip install xlrd 1.2 xlrd介紹:xlrd是python環境下