c++中的set容器介紹及操作大全
??一、核心特性??
??唯一性與自動(dòng)排序??std::set存儲(chǔ)的元素??唯一且默認(rèn)升序排列??(通過std::less實(shí)現(xiàn))。插入重復(fù)元素會(huì)被自動(dòng)忽略:
set<int> s = {3, 1, 2, 2}; // 實(shí)際存儲(chǔ) {1, 2, 3}- ??底層實(shí)現(xiàn)??:紅黑樹(自平衡二叉搜索樹),保證插入、刪除、查找的??時(shí)間復(fù)雜度為O(log n)??
??元素不可修改??
元素值即鍵(Key),修改會(huì)破壞紅黑樹結(jié)構(gòu)。迭代器類型為const_iterator,禁止寫操作:
auto it = s.find(2); *it = 4; // 編譯錯(cuò)誤!元素不可直接修改
- 修改的正確姿勢(shì)??:先刪除舊值,再插入新值
??無隨機(jī)訪問??
不支持operator[]或下標(biāo)訪問,遍歷??必須依賴迭代器??(雙向迭代器,僅支持++/--)
??? ??二、基本操作??
??1. 初始化與賦值??
| ??方式?? | ??示例?? |
|---|---|
| 默認(rèn)構(gòu)造 | set<int> s; |
| 初始化列表 | set<int> s = {1, 3, 2}; → {1, 2, 3} |
| 迭代器范圍初始化 | vector<int> v{5,4,3}; set<int> s(v.begin(), v.end()); |
| 自定義排序規(guī)則 | set<int, greater<int>> s;(降序)4 12 |
??2. 增刪查操作??
| ??操作?? | ??函數(shù)?? | ??示例?? | ??返回值?? |
|---|---|---|---|
| 插入元素 | insert(value) | s.insert(4); | pair<iter, bool>(成功時(shí)bool=true) |
| 刪除元素 | erase(key) / erase(iter) | s.erase(3); 或 s.erase(s.begin()); | 返回被刪元素后的迭代器 |
| 查找元素 | find(key) | auto it = s.find(2); | 找到返回迭代器,否則返回s.end() |
| 統(tǒng)計(jì)元素存在性 | count(key) | if (s.count(2)) { ... } | 0或1(因元素唯一)1 9 |
??3. 遍歷方式??
// 迭代器遍歷
for (auto it = s.begin(); it != s.end(); ++it) {
cout << *it << " ";
}
// 范圍循環(huán)(C++11)
for (int val : s) {
cout << val << " ";
}?? ??三、高級(jí)操作??
??1. 自定義排序規(guī)則??
通過函數(shù)對(duì)象或Lambda實(shí)現(xiàn)復(fù)雜排序:
struct CaseInsensitiveCompare {
bool operator()(const string& a, const string& b) const {
return tolower(a[0]) < tolower(b[0]); // 首字母不區(qū)分大小寫
}
};
set<string, CaseInsensitiveCompare> s;??2. 范圍查詢(lower_bound / upper_bound)??
set<int> s = {10, 20, 30, 40};
auto low = s.lower_bound(20); // 首個(gè) ≥20 的元素 → 20
auto high = s.upper_bound(30); // 首個(gè) >30 的元素 → 40- ??應(yīng)用場(chǎng)景??:快速定位有序數(shù)據(jù)中的區(qū)間
??3. 結(jié)構(gòu)體存儲(chǔ)??
需重載operator<:
struct Person {
string name;
int age;
bool operator<(const Person& p) const {
return age < p.age; // 按年齡升序
}
};
set<Person> s = {{"Alice", 30}, {"Bob", 25}};?? ??四、性能對(duì)比:set vs vector??
| ??操作?? | set | vector | ??適用場(chǎng)景?? |
|---|---|---|---|
| ??插入/刪除?? | O(log n)(任意位置) | O(n)(非尾部操作) | 頻繁中間插入/刪除 → ??選set?? |
| ??查找?? | O(log n)(二分查找) | O(n)(線性遍歷) | 高頻查找 → ??選set?? |
| ??隨機(jī)訪問?? | ? 不支持 | ? O(1) | 按索引訪問 → ??選vector?? |
| ??內(nèi)存占用?? | 較高(樹節(jié)點(diǎn)開銷) | 較低(連續(xù)內(nèi)存) | 內(nèi)存敏感 → ??選vector?? |
| ??元素順序?? | 自動(dòng)排序 | 插入順序 | 需有序 → ??選set?? |
?? ??關(guān)鍵結(jié)論??:
- ??唯一性+有序性??需求優(yōu)先選
set - ?隨機(jī)訪問+連續(xù)存儲(chǔ)??需求優(yōu)先選
vector
?? ??五、典型應(yīng)用場(chǎng)景??
??數(shù)據(jù)去重與排序??
從重復(fù)數(shù)據(jù)中提取唯一有序序列:
vector<int> data = {5, 3, 5, 2, 1};
set<int> unique_sorted(data.begin(), data.end()); // {1, 2, 3, 5}??高效存在性檢查??
黑名單/白名單快速過濾:
set<string> blacklist = {"user1", "user2"};
if (blacklist.find(input_user) != blacklist.end()) block_user();??范圍統(tǒng)計(jì)與區(qū)間查詢??
成績(jī)分級(jí)、區(qū)間數(shù)據(jù)分析:
set<int> scores = {60, 75, 85, 90};
auto pass = scores.lower_bound(60); // ≥60的第一個(gè)元素?? ??六、避坑指南??
- ??迭代器失效問題??
刪除元素時(shí),??僅被刪元素的迭代器失效??,其他迭代器仍有效。
- ??無法修改元素值??
“修改”需先刪除再插入:
auto it = s.find(old_val);
if (it != s.end()) {
s.erase(it);
s.insert(new_val); // 安全修改
}- ??自定義類型必須重載
operator<?? - 否則編譯失?。t黑樹需比較規(guī)則)。
?? ??總結(jié)??
- ??核心優(yōu)勢(shì)??:自動(dòng)去重、有序存儲(chǔ)、O(log n)高效操作;
- ??核心局限??:無隨機(jī)訪問、內(nèi)存開銷較高;
- ??替代方案??:
- 需重復(fù)元素 →
multiset; - 需O(1)查找 →
unordered_set(哈希表實(shí)現(xiàn),無序)。
- 需重復(fù)元素 →
到此這篇關(guān)于c++中的set容器介紹及操作大全的文章就介紹到這了,更多相關(guān)c++ set容器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
VC實(shí)現(xiàn)A進(jìn)程窗口嵌入到B進(jìn)程窗口中顯示的方法
這篇文章主要介紹了VC實(shí)現(xiàn)A進(jìn)程窗口嵌入到B進(jìn)程窗口中顯示的方法,對(duì)于理解windows程序運(yùn)行原理的進(jìn)程問題有一定的幫助,需要的朋友可以參考下2014-07-07
C語(yǔ)言中volatile關(guān)鍵字的作用與使用案例教程
這篇文章主要介紹了C語(yǔ)言中volatile關(guān)鍵字的作用與使用案例教程,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是本文的詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
OpenCV實(shí)現(xiàn)簡(jiǎn)單攝像頭視頻監(jiān)控程序
這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)簡(jiǎn)單攝像頭視頻監(jiān)控程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08
C++實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12
使用Qt封裝一個(gè)發(fā)送http請(qǐng)求通用類
這篇文章主要為大家詳細(xì)介紹了如何使用Qt封裝一個(gè)通用類,可以通過QNetworkRequest和QNetworkReply進(jìn)行http請(qǐng)求,感興趣的可以了解一下2024-12-12
C++開發(fā)之PugiXML庫(kù)基礎(chǔ)用法示例詳解
PugiXML庫(kù)是一個(gè)功能強(qiáng)大、簡(jiǎn)單易用的C++ XML解析庫(kù),它提供了一組方便的函數(shù)來解析、創(chuàng)建和修改XML文檔,本文介紹了如何使用PugiXML庫(kù)來解析、創(chuàng)建和修改XML文檔,以及如何處理錯(cuò)誤和異常,感興趣的朋友跟隨小編一起看看吧2024-03-03
C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易學(xué)生成績(jī)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易學(xué)生成績(jī)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12
使用C語(yǔ)言生成圖片的base64編碼的代碼實(shí)現(xiàn)
Base64編碼是一種廣泛使用的編碼方案,將任意二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為可打印的ASCII字符字符串,在實(shí)際應(yīng)用中,Base64編碼常見于電子郵件附件、數(shù)據(jù)庫(kù)中存儲(chǔ)非文本數(shù)據(jù)等多種場(chǎng)景,本文將給大家介紹使用C語(yǔ)言生成圖片的base64編碼的代碼實(shí)現(xiàn),需要的朋友可以參考下2024-08-08
C++超詳細(xì)講解構(gòu)造函數(shù)與析構(gòu)函數(shù)的用法及實(shí)現(xiàn)
構(gòu)造函數(shù)主要作用在于創(chuàng)建對(duì)象時(shí)為對(duì)象的成員屬性賦值,構(gòu)造函數(shù)由編譯器自動(dòng)調(diào)用,無須手動(dòng)調(diào)用;析構(gòu)函數(shù)主要作用在于對(duì)象銷毀前系統(tǒng)自動(dòng)調(diào)用,執(zhí)行一?些清理工作2022-05-05

