柚子快報激活碼778899分享:【C++】set詳解
柚子快報激活碼778899分享:【C++】set詳解
?博客主頁:https://blog.csdn.net/2301_779549673 ?歡迎點贊 ? 收藏 ?留言 ? 如有錯誤敬請指正! ?本文由 JohnKi 原創(chuàng),首發(fā)于 CSDN? ?未來很長,值得我們全力奔赴更美好的生活?
文章目錄
?前言???? 一、set類的介紹????二、set的構造和迭代器????三、set的增刪查????四、insert和迭代器遍歷使用樣例?總結
?前言
Set 是 C++ 標準模板庫(STL)中的一種關聯(lián)容器,主要用于存儲不重復且有序的元素。其內部實現(xiàn)采用紅黑樹,這種數(shù)據(jù)結構具有自動排序的特性,能夠高效地進行插入、刪除和查找操作。
紅黑樹是一種平衡二叉搜索樹,它的統(tǒng)計性能優(yōu)于一般的平衡二叉樹。在 set 中,每個元素的值都唯一,并且元素的值不能直接被改變。這是因為 set 中的元素值就是其鍵值,關系到 set 元素的排列規(guī)則。如果任意改變 set 的元素值,會嚴重破壞 set 的組織。
Set 的迭代器被定義為底層紅黑樹的 const_iterator,杜絕了寫入操作。這意味著我們不能通過 set 的迭代器直接修改元素的值。例如,當我們嘗試通過 set 的迭代器改變元素的值時,編譯器會報錯。
此外,當對 set 進行元素新增操作(insert)或刪除操作(erase)時,操作之前的所有迭代器,在操作完成之后都依然有效,被刪除的那個元素的迭代器必然是個例外。這種特性使得 set 在進行動態(tài)操作時,能夠保持迭代器的有效性,方便了程序的編寫和維護。
總的來說,C++ 中的 set 容器以其獨特的特性和高效的內部實現(xiàn),為程序員提供了一種方便、可靠的數(shù)據(jù)存儲和操作方式。
???? 一、set類的介紹
set的聲明如下,T就是set底層關鍵字的類型.set默認要求T支持小于比較,如果不支持或者想按自己的需求走可以自行實現(xiàn)仿函數(shù)傳給第二個模版參數(shù)set底層存儲數(shù)據(jù)的內存是從空間配置器申請的,如果需要可以自己實現(xiàn)內存池,傳給第三個參數(shù)。一般情況下,我們都不需要傳后兩個模版參數(shù)。set底層是用紅黑樹實現(xiàn),增刪查效率是O(l0gN),迭代器遍歷是走的搜索樹的中序,所以是有序的。前面部分我們已經學習了vector/list等容器的使用,STL容器接口設計,高度相似,所以這里我們就不再一個接口一個接口的介紹,而是直接帶著大家看文檔,挑比較重要的接口進行介紹。
template < class T, // set::key_type/value_type
class Compare = less
class Alloc = allocator
> class set;
????二、set的構造和迭代器
set的構造我們關注以下幾個接口即可。set的支持正向和反向迭代遍歷,遍歷默認按升序順序,因為底層是二叉搜索樹,迭代器遍歷走的中序;支持迭代器就意味著支持范圍for,set的iterator和const iterator都不支持迭代器修改數(shù)據(jù),修改關鍵字數(shù)據(jù),破壞了底層搜索樹的結構。
Set 的構造方式主要有以下幾種: 默認構造函數(shù):set st;,創(chuàng)建一個空的 set。例如:set mySet;。 拷貝構造函數(shù):set(const set &st);,創(chuàng)建一個新的 set,它是現(xiàn)有 set 的副本。例如:set mySet = {1, 2, 3}; set anotherSet(mySet);。 使用區(qū)間構造:可以用一個已有的區(qū)間中的元素構造 set,如set s2(s1.begin(), s1.end());。 賦值操作可以使用重載的等號操作符:set& operator=(const set &st);,將一個 set 的內容賦值給另一個已經存在的 set。例如:set mySet = {1, 2, 3}; set anotherSet; anotherSet = mySet;。
// empty (1) ?參默認構造
explicit set (const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
// range (2) 迭代器區(qū)間構造
template
set (InputIterator first, InputIterator last,
const key_compare& comp = key_compare(),
const allocator_type& = allocator_type());
// copy (3) 拷?構造
set (const set& x);
// initializer list (5) initializer 列表構造
set (initializer_list
const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
// 迭代器是?個雙向迭代器
iterator -> a bidirectional iterator to const value_type
// 正向迭代器
iterator begin();
iterator end();
// 反向迭代器
reverse_iterator rbegin();
reverse_iterator rend();
????三、set的增刪查
set的增刪查關注以下幾個接口即可:
插入元素 使用insert方法可以在 set 中插入元素。例如:mySet.insert(5);。如果元素已存在,插入操作將被忽略。insert方法的返回值是個pair結構的對組,pair
Member types
key_type -> The first template parameter (T)
value_type -> The first template parameter (T)
// 單個數(shù)據(jù)插?,如果已經存在則插?失敗
pair
// 列表插?,已經在容器中存在的值不會插?
void insert (initializer_list
// 迭代器區(qū)間插?,已經在容器中存在的值不會插?
template
void insert (InputIterator first, InputIterator last);
// 查找val,返回val所在的迭代器,沒有找到返回end()
iterator find (const value_type& val);
// 查找val,返回Val的個數(shù)
size_type count (const value_type& val) const;
// 刪除?個迭代器位置的值
iterator erase (const_iterator position);
// 刪除val,val不存在返回0,存在返回1
size_type erase (const value_type& val);
// 刪除?段迭代器區(qū)間的值
iterator erase (const_iterator first, const_iterator last);
// 返回?于等val位置的迭代器
iterator lower_bound (const value_type& val) const;
// 返回?于val位置的迭代器
iterator upper_bound (const value_type& val) const;
易錯點提示 end()函數(shù)的正確用法:end()函數(shù)的作用不是用于返回最后一個元素,而是用于返回 set 中最后一個元素的后一個位置的指針。如果一個 set 中的元素是<1,2,3>,那么返回的就是元素 3 之后的一位的指針。如果要看最后一個元素,可以使用遍歷的方式找到最后一個元素,或者使用其他方法。
不能直接 copy:不能將一個 set 直接使用=號賦值給另外一個 set。如下面的寫法就是錯誤的:set set1; set set2 = set1;。這種寫法會導致編譯錯誤或者不可預期的結果。在 C++ 中,set 的賦值操作需要使用特定的方法,如拷貝構造函數(shù)或者賦值運算符重載。
????四、insert和迭代器遍歷使用樣例
#include
#include
using namespace std;
int main() {
// 去重+升序排序
set
// 去重+降序排序(給?個?于的仿函數(shù))
//set
s.insert(5);
s.insert(2);
s.insert(7);
s.insert(5);
//set
auto it = s.begin();
while (it != s.end()) {
// error C3892: “it”: 不能給常量賦值
// *it = 1;
cout << *it << " ";
++it;
}
cout << endl;
// 插??段initializer_list列表值,已經存在的值插?失敗
s.insert({ 2, 8, 3, 9 });
for (auto e : s) {
cout << e << " ";
}
cout << endl;
set
// 遍歷string?較ascll碼??順序遍歷的
for (auto& e : strset) {
cout << e << " ";
}
cout << endl;
}
?總結
本篇博文對 set 做了一個較為詳細的介紹,不知道對你有沒有幫助呢
覺得博主寫得還不錯的三連支持下吧!會繼續(xù)努力的~
柚子快報激活碼778899分享:【C++】set詳解
精彩文章
本文內容根據(jù)網(wǎng)絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉載請注明,如有侵權,聯(lián)系刪除。