1. 程式人生 > >C++ STL set容器常用用法

C++ STL set容器常用用法

set是STL中一種標準關聯容器。它底層使用平衡的搜尋樹——紅黑樹實現,插入刪除操作時僅僅需要指標操作節點即可完成,不涉及到記憶體移動和拷貝,所以效率比較高。set,顧名思義是“集合”的意思,在set中元素都是唯一的,而且預設情況下會對元素自動進行升序排列,支援集合的交(set_intersection),差(set_difference) 並(set_union),對稱差(set_symmetric_difference) 等一些集合上的操作,如果需要集合中的元素允許重複那麼可以使用multiset。

1.set容器的常用操作

使用時注意包含標頭檔案<set>    std::set and std::multiset associative containers

s.begin()      返回set容器的第一個元素

s.end()      返回set容器的最後一個元素

s.clear()       刪除set容器中的所有的元素

s.empty()     判斷set容器是否為空

s.insert()      插入一個元素

s.erase()       刪除一個元素

s.size()     返回當前set容器中的元素個數

set模板原型://Key為元素(鍵值)型別

template <class Key, class Compare=less<Key>, class Alloc=STL_DEFAULT_ALLOCATOR(Key) >

2.set容器的建立

#include <iostream>
#include <set>
#include <functional>
using namespace std;
set<int> s;

int main(){
   set<int > seta; //預設是小於比較器less<int>的set
set<int, greater<int> > setb; //建立一個帶大於比較器的set,需包含標頭檔案functional int a[5] = {1,2,3,4,5}; set<int > setc(a,a+5); //陣列a初始化一個set; set<int > setd(setc.begin(),setc.end()); //setc初始化一個set //上述兩例均為區間初始化 set<int > sete(setd); //拷貝構造建立set return 0; }

3.set容器的增刪改查

①插入

#include <iostream>
#include <set>
using namespace std;
set<int >s;
void setprint(int cnt){
    cout << "Test output :" << cnt << ":" << endl;
    for(set<int>::iterator it = s.begin(); it!= s.end(); it++)
        cout << *it << " ";
    puts("");
    return ;
}
int main(){
    int cnt = 1;
    s.insert(1);
    s.insert(2);
    s.insert(5);
    setprint(cnt++);

    s.insert(2); //set只允許用一個值出現一次,要插入相同元素請用multiset
    setprint(cnt++);

    int a[4] = {11,12,13,14};
    s.insert(a,a+4); //將區間[a, a+4]裡的元素插入容器
    setprint(cnt++);

    return 0;
}

插入

②刪除

s.erase()       刪除一個元素

s.clear()       刪除set容器中的所有的元素
#include <iostream>
#include <set>
using namespace std;
set<int >s;
void setprint(int cnt){
    cout << "Test output :" << cnt << ":" << endl;
    for(set<int>::iterator it = s.begin(); it!= s.end(); it++)
        cout << *it << " ";
    puts("");
    return ;
}

int main(){
    int cnt = 1;
    for(int i = 1; i < 11; i++){
        s.insert(i);
    }
    setprint(cnt++);

    s.erase(9); //根據元素刪除
    setprint(cnt++);

    set<int>::iterator ita = s.begin();
    set<int>::iterator itb = s.begin();
    s.erase(ita);  //刪除迭代器指向位置的元素
    setprint(cnt++);

    ita = s.begin();
    itb = s.begin();
    itb++;itb++;
    s.erase(ita,itb); //刪除區間[ita,itb)的元素
    setprint(cnt);
    s.clear();
    return 0;
}

刪除

③修改

不能直接修改容器內資料,所以只能刪除某元素再插入要修改的數值。

④查詢

s.find()        查詢一個元素,如果容器中不存在該元素,返回值等於s.end()
#include <iostream>
#include <set>
using namespace std;
set<int >s;
void setprint(int cnt){
    cout << "Test output :" << cnt << ":" << endl;
    for(set<int>::iterator it = s.begin(); it!= s.end(); it++)
        cout << *it << " ";
    puts("");
    return ;
}
int main(){
    int cnt = 1;
    s.insert(1);
    s.insert(2);
    s.insert(5);
    setprint(cnt++);

    if(s.find(2) != s.end()) 
        cout << "2 is existent" << endl;
    else 
        cout << "2 is non-existent" << endl;
    if(s.find(3) == s.end()) 
        cout << "3 is non-existent" << endl;
    else 
        cout << "2 is existent" << endl;
    return 0;
}

查詢

4.set的其他常用操作

s.lower_bound() 返回第一個大於或等於給定關鍵值的元素

s.upper_bound() 返回第一個大於給定關鍵值的元素

s.equal_range() 返回一對定位器,分別表示 第一個大於或等於給定關鍵值的元素 和 第一個大於給定關鍵值
                的元素,這個返回值是一個pair型別,如果這一對定位器中哪個返回失敗,就會等於
                s.end()
#include <iostream>
#include <set>
using namespace std;

int main(){
    set<int> s;
    s.insert(1);
    s.insert(2);
    s.insert(5);

    cout << "lower_bound & upper_bound test:" << endl;

    cout << "第一個大於或等於3的元素: " << *s.lower_bound(3) << endl;
    cout << "第一個大於或等於2的元素: " <<*s.lower_bound(2) << endl;
    cout << "第一個大於2的元素: " <<*s.upper_bound(2) << endl;

    cout << "equal_range test:" << endl;

    cout << "第一個大於或等於2的元素: " <<  *s.equal_range(2).first << endl;
    cout << "第一個大於2的元素: " << *s.equal_range(2).second << endl;
    return 0;
}

樣例

②判斷元素是否在set中 & 判斷set是否為空

#include <iostream>
#include <set>
#include <functional>
using namespace std;

int main(){
    set<int > s;
    if(s.empty()) cout << "容器為空" << endl;
    s.insert(1);
    if(!s.empty()) cout << "容器不為空" << endl;

    if(s.count(1)) cout << "1在容器中" << endl;
    if(!s.count(2)) cout << "2不在容器中" << endl;
    return 0;
}

是否為空

③自定義比較函式

#include <iostream>
#include <set>
#include <functional>
using namespace std;

struct cmp{
    bool operator () (const int &a, const int &b){
        return a > b;
    }
};
set<int, cmp>s; //自定義排序函式構造set
void setprint(int cnt){
    cout << "Test output :" << cnt << ":" << endl;
    for(set<int,cmp>::iterator it = s.begin(); it!= s.end(); it++)
        cout << *it << " ";
    puts("");
    return ;
}
int main(){
    s.insert(1);
    s.insert(2);
    s.insert(6);
    setprint(1);
    return 0;
}

自定義比較函式

以上就是刷題必備的set用法,熟練掌握,要用時別用錯就成。

至於求並、交、差、對稱差等操作,暫不細說,使用時要包含標頭檔案”algorithm”。
此外還有unordered_set和unordered_multiset,為set和multiset的無序版,使用時要包含標頭檔案”unordered_set”。