網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
一、set
1.1 set的介紹
首先要知道set的底層是由紅黑樹(shù)(平衡二叉搜索樹(shù))實(shí)現(xiàn)的。
T
set存放元素類(lèi)型,底層是<value, value>的鍵值對(duì)。Compare
仿函數(shù),因?yàn)閷?shí)現(xiàn)搜索樹(shù)需要比較。
1.2 set的使用
1.2.1 set的構(gòu)造
void test_set() { // 默認(rèn)構(gòu)造 set<int> s1; // 迭代器區(qū)間構(gòu)造 int a[] = { 1, 2, 3, 4 }; set<int> s2(a, a + 4); // 拷貝構(gòu)造(深拷貝) set<int> s3(s2); for (int e : s2) cout << e << " "; cout << endl; for (int e : s3) cout << e << " "; cout << endl; }
1.2.2 set的迭代器
可以看到set有反向迭代器。
void test1() { set<int> s;// 排序+去重 s.insert(1); s.insert(2); s.insert(3); s.insert(1); s.insert(3); s.insert(4); // 正向迭代器 set<int>::iterator it1 = s.begin(); while (it1 != s.end()) { cout << *it1++ << " "; } cout << endl; // 反向迭代器 set<int>::reverse_iterator it2 = s.rbegin(); while (it2 != s.rend()) { cout << *it2++ << " "; } cout << endl; }
因?yàn)閟et的仿函數(shù)默認(rèn)參數(shù)是less<T>
,所以排的是升序,如果我們想排降序就可以傳遞greater<T>
。
void test1() { set<int, greater<int>> s;// 排序+去重 s.insert(1); s.insert(2); s.insert(3); s.insert(1); s.insert(3); s.insert(4); // 正向迭代器 set<int>::iterator it1 = s.begin(); while (it1 != s.end()) { cout << *it1++ << " "; } cout << endl; // 反向迭代器 set<int>::reverse_iterator it2 = s.rbegin(); while (it2 != s.rend()) { cout << *it2++ << " "; } cout << endl; }
1.2.3 set的修改
1.2.3.1 insert && find && erase
void test2() { set<int> s; s.insert(1); s.insert(2); s.insert(3); s.insert(4); s.insert(5); set<int>::iterator it = s.find(3); s.erase(it); for (auto& e : s) { cout << e << " "; } cout << endl; }
1.2.3.2 count
傳進(jìn)去一個(gè)元素?cái)?shù)值,返回該元素的個(gè)數(shù)。
void test2() { set<int> s; s.insert(1); s.insert(2); s.insert(3); s.insert(4); s.insert(5); cout << s.count(2) << endl; cout << s.count(6) << endl; }
因?yàn)閟et的元素是唯一的,所以在set這里count可以用find來(lái)代替,但是在后面的multiset
可以插入重復(fù)的元素,count就可以統(tǒng)計(jì)該元素的個(gè)數(shù)。
1.3 multiset
multiset和set的區(qū)別是它可以插入重復(fù)的元素。其他的接口跟set一致。頭文件也跟set相同。
void test3() { multiset<int> ms; ms.insert(1); ms.insert(1); ms.insert(2); ms.insert(3); ms.insert(4); for (auto& e : ms) { cout << e << " "; } cout << endl; cout << "count(1): " << ms.count(1) << endl; }
另外使用find查找時(shí),如果有多個(gè)值相同,find返回的值是中序的第一個(gè)。
二、map
2.1 map的介紹
key
鍵值對(duì)中key的類(lèi)型T
鍵值對(duì)中value的類(lèi)型
注意:
1?? map中的元素總是按照鍵值key進(jìn)行比較排序的。
2?? map支持下標(biāo)訪問(wèn)符,即在[]中放入key,就可以找到與key對(duì)應(yīng)的value。
2.2 map的使用
構(gòu)造和迭代器跟上面的set類(lèi)似,就不過(guò)多闡述。
2.2.1 map的修改
2.2.1.1 insert
void test4() { map<string, int> m; m.insert(pair<string, int>("a", 1));// 匿名對(duì)象 m.insert(make_pair("b", 2));// 簡(jiǎn)化寫(xiě)法 m.insert(make_pair("c", 2)); m.insert(make_pair("d", 2)); map<string, int>::iterator it = m.begin(); while (it != m.end()) { cout << (*it).first << "->" << (*it).second << endl; it++; } }
make_pair:函數(shù)模板,不需要像pair一樣顯示聲明類(lèi)型,而是通過(guò)傳參自動(dòng)推導(dǎo)。
2.2.1.2 統(tǒng)計(jì)次數(shù)
1?? 使用find,利用迭代器
int main() { string arr[] = { "北京", "武漢", "廣州", "上海", "北京", "北京", "廣州", "上海", "上海" }; map<string, int> cnt; for (auto& e : arr) { map<string, int>::iterator fd = cnt.find(e); if (fd == cnt.end()) { cnt.insert(make_pair(e, 1)); } else { fd->second++; } } for (auto& e : cnt) { cout << e.first << "->" << e.second << endl; } return 0; }
2?? 使用[]
int main() { string arr[] = { "北京", "武漢", "廣州", "上海", "北京", "北京", "廣州", "上海", "上海" }; map<string, int> cnt; for (auto& e : arr) { cnt[e]++; } for (auto& e : cnt) { cout << e.first << "->" << e.second << endl; } return 0; }
[]
可以用來(lái)插入、修改、查找
[] -> (*((this->insert(make_pair(k,mapped_type()))).first)).second // 等價(jià)于 V& operator[](const K& k) { pair<iterator, bool> ret = insert(make_pair(k, V())); return ret.first->second; }
這里就可以看出使用[]
的時(shí)候要注意:如果沒(méi)有它會(huì)直接插入。
所以我們想插入就可以:
int main() { map<string, int> m; // 插入 m["廣西"]; m["廣東"] = 1; for (auto& e : m) { cout << e.first << "->" << e.second << endl; } return 0; }
當(dāng)我們想要修改的時(shí)候不能用insert,因?yàn)?strong>只要key相同就會(huì)插入失敗。
int main() { map<string, int> m; // 插入 m["廣西"]; m["廣東"] = 1; m.insert(make_pair("廣東", 2));// 插入失敗 for (auto& e : m) { cout << e.first << "->" << e.second << endl; } return 0; }
先要修改可以:
m["廣東"] = 2;
key不在就是插入,key在就是查找。
2.3 multimap
int main() { multimap<string, int> mm; mm.insert(make_pair("北京", 1)); mm.insert(make_pair("北京", 2)); mm.insert(make_pair("北京", 1)); mm.insert(make_pair("上海", 1)); for (auto& e : mm) { cout << e.first << "->" << e.second << endl; } return 0; }
multimap容器與map容器的底層實(shí)現(xiàn)以及成員函數(shù)的接口都是基本一致,而multimap的key可以重復(fù)。注意multimap沒(méi)有[]
。
使用multimap統(tǒng)計(jì)次數(shù):
int main() { multimap<string, int> mm; string arr[] = { "北京", "武漢", "廣州", "上海", "北京", "北京", "廣州", "上海", "上海" }; for (auto& e : arr) { map<string, int>::iterator fd = mm.find(e); if (fd == mm.end()) { mm.insert(make_pair(e, 1)); } else { fd->second++; } } for (auto& e : mm) { cout << e.first << "->" << e.second << endl; } return 0; }
補(bǔ)充:set和map的區(qū)別
- map中的元素是key-value(關(guān)鍵字—值)對(duì):關(guān)鍵字起到索引的作用,值則表示與索引相關(guān)聯(lián)的數(shù)據(jù);Set與之相對(duì)就是關(guān)鍵字的簡(jiǎn)單集合,set中每個(gè)元素只包含一個(gè)關(guān)鍵字。
- set的迭代器是const的,不允許修改元素的值。map允許修改value,但不允許修改key。其原因是因?yàn)閙ap和set是根據(jù)關(guān)鍵字排序來(lái)保證其有序性的,如果允許修改key的話,那么首先需要?jiǎng)h除該鍵,然后調(diào)節(jié)平衡,再插入修改后的鍵值,調(diào)節(jié)平衡,如此一來(lái),嚴(yán)重破壞了map和set的結(jié)構(gòu),導(dǎo)致iterator失效,不知道應(yīng)該指向改變前的位置,還是指向改變后的位置。所以STL中將set的迭代器設(shè)置成const,不允許修改迭代器的值;而map的迭代器則不允許修改key值,允許修改value值。
- map支持下標(biāo)操作,set不支持下標(biāo)操作。map可以用key做下標(biāo),map的下標(biāo)運(yùn)算符[ ]將關(guān)鍵碼作為下標(biāo)去執(zhí)行查找,如果關(guān)鍵碼不存在,則插入一個(gè)具有該關(guān)鍵碼和mapped_type類(lèi)型默認(rèn)值的元素至map中,因此下標(biāo)運(yùn)算符[ ]在map應(yīng)用中需要慎用,const_map不能用,只希望確定某一個(gè)關(guān)鍵值是否存在而不希望插入元素時(shí)也不應(yīng)該使用,mapped_type類(lèi)型沒(méi)有默認(rèn)值也不應(yīng)該使用。如果find能解決需要,盡可能用find。
總結(jié)
原文鏈接:https://blog.csdn.net/qq_66314292/article/details/129131964
- 上一篇:沒(méi)有了
- 下一篇:沒(méi)有了
相關(guān)推薦
- 2022-12-15 Rust實(shí)現(xiàn)一個(gè)表達(dá)式Parser小結(jié)_Rust語(yǔ)言
- 2023-03-27 React里的Fragment標(biāo)簽的具體使用_React
- 2022-07-20 python計(jì)算機(jī)視覺(jué)實(shí)現(xiàn)全景圖像拼接示例_python
- 2021-12-07 詳解C語(yǔ)言編程之thread多線程_C 語(yǔ)言
- 2022-10-20 Swift初始化方法的使用介紹_Swift
- 2022-11-09 React?錯(cuò)誤邊界Error?Boundary使用示例解析_React
- 2022-02-12 android button的圓角邊框及點(diǎn)擊效果實(shí)現(xiàn)
- 2022-08-27 C++中Boost的智能指針shared_ptr_C 語(yǔ)言
- 欄目分類(lèi)
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支