C++_STL_map與set

1. 關聯式容器

在初階階段,我們已經接觸過STL中的部分容器,比如:vector、list、deque、 forward_list(C++11)等,這些容器統稱為序列式容器,因為其底層為線性序列的數據結構,里面 存儲的是元素本身。那什么是關聯式容器?它與序列式容器有什么區別?

關聯式容器也是用來存儲數據的,與序列式容器不同的是,其里面存儲的是結構的 鍵值對,在數據檢索時比序列式容器效率更高。

2. 鍵值對

用來表示具有一一對應關系的一種結構,該結構中一般只包含兩個成員變量key和value,key代 表鍵值,value表示與key對應的信息。比如:現在要建立一個英漢互譯的字典,那該字典中必然 有英文單詞與其對應的中文含義,而且,英文單詞與其中文含義是一一對應的關系,即通過該應 該單詞,在詞典中就可以找到與其對應的中文含義。

3. 樹形結構的關聯式容器

根據應用場景的不桶,STL總共實現了兩種不同結構的管理式容器:樹型結構與哈希結構。樹型結 構的關聯式容器主要有四種:map、set、multimap、multiset。

這四種容器的共同點是:使 用平衡搜索樹(即紅黑樹)作為其底層結果容器中的元素是一個有序的序列。下面一依次介紹每一 個容器。

3.1? set

set - C++ Reference

翻譯:

1. set是按照一定次序存儲元素的容器

2. 在set中,元素的value也標識它(value就是key,類型為T),并且每個value必須是唯一的。 set中的元素不能在容器中修改(元素總是const),但是可以從容器中插入或刪除它們。

3. 在內部,set中的元素總是按照其內部比較對象(類型比較)所指示的特定嚴格弱排序準則進行 排序。

4. set容器通過key訪問單個元素的速度通常比unordered_set容器慢,但它們允許根據順序對 子集進行直接迭代。

5. set在底層是用二叉搜索樹(紅黑樹)實現的。

注意:

1. 與map/multimap不同,map/multimap中存儲的是真正的鍵值對,set中只放 value,但在底層實際存放的是由構成的鍵值對。

2. set中插入元素時,只需要插入value即可,不需要構造鍵值對。

3. set中的元素不可以重復(因此可以使用set進行去重)。

4. 使用set的迭代器遍歷set中的元素,可以得到有序序列

5. set中的元素默認按照小于來比較

6. set中查找某個元素,時間復雜度為:log_2 n

?7. set中的元素不允許修改(為什么?)

8. set中的底層使用二叉搜索樹(紅黑樹)來實現。

關于set的使用就不多說了關鍵看一些我們之前沒見到的接口

set的拷貝代價很大但是搜索的代價很小

同時要注意這個lower_bound 和upper_bound? ?這兩個接口

這里是找這兩個區間的值

lower_bound(20)->就是找大于等于key = 25的節點

upper_bound(50)->就是找key>50的這個節點

這樣形成一個左閉右開的結構,才可以將我們給的區間里面的東西刪除完(迭代器里面的所有操作幾乎都是左閉右開的)

而這個count 和equal_range對于met是沒有什么意義的,應為set不允許重復,但是對于下面的multiset就很有意義了

3.2multiset

multiple:多樣的,其實這個multiset就是可以存儲重復的數據

multiset介紹multiset - C++ Reference

具體使用:

void Test_mutiset()
{int arr[] = { 2,4,5,6,7,843,2,4,5,7,9 ,11,45 };multiset<int> s1(arr, arr + (sizeof(arr) / sizeof(int)));for (const auto& e : s1){cout << e << " ";}cout << endl;//find查找(重復數據)返回中序的第一個multiset<int>::iterator it = s1.find(4);while (it != s1.end()){cout << *it << " ";++it;}cout << endl;cout << s1.count(2) << endl;pair<multiset<int>::iterator, multiset<int>::iterator> eq = s1.equal_range(2);while (eq.first != eq.second){cout << *(eq.first) << " ";++eq.first;}cout << endl;}

這里的equal_range返回的是一個pair,我們一般用auto來接收,要不然要寫一大堆?

3.3map

講之前先學習一下pair

pair - C++ Reference

這個pair其實就是一個類(我們也喜歡叫鍵值對),里面有first和second兩個位置可以存儲數據,這就方便了,在key_value

(map)里面我們就把這兩個放到pair里面,這樣對于一個函數返回的時候返回一個pair也方便

map - C++ Reference

翻譯:

1. map是關聯容器,它按照特定的次序(按照key來比較)存儲由鍵值key和值value組合而成的元 素。

2. 在map中,鍵值key通常用于排序和惟一地標識元素,而值value中存儲與此鍵值key關聯的 內容。鍵值key和值value的類型可能不同,并且在map的內部,key與value通過成員類型 value_type綁定在一起,為其取別名稱為pair: typedef pair value_type;

3. 在內部,map中的元素總是按照鍵值key進行比較排序的。

4. map中通過鍵值訪問單個元素的速度通常比unordered_map容器慢,但map允許根據順序 對元素進行直接迭代(即對map中的元素進行迭代時,可以得到一個有序的序列)。

5. map支持下標訪問符,即在[]中放入key,就可以找到與key對應的value。

6. map通常被實現為二叉搜索樹(更準確的說:平衡二叉搜索樹(紅黑樹))。

map的插入就比較繁瑣,(單參數才能接受隱式類型轉化)

void Test_map()
{map<string,string> dict;//插入的方法pair<string, string> p1("insert", "插入");dict.insert(p1);dict.insert(pair<string,string>("right", "右邊"));dict.insert(make_pair("sort", "排序"));dict.insert({ "queue","隊列" });auto it = dict.begin();while (it != dict.end()){//pair沒有重載*所以打印的時候就訪問first,second//cout << (*it).first << ":" <<(*it).second << endl;cout << it->first  << ":" << it->second << endl;++it;}cout << endl;
}

第三種也是比較常用的這個就是一個庫里面的一個函數,方便構造

最后一種插入方法其實就是隱式類型轉換

這里是c++11支持的,而c++98不支持

要注意:map和set里面的key都不能修改,因為改了話就改變了搜索樹的結構

set:直接將迭代器全搞為const迭代器,但是map不敢這樣搞,因為map要允許修改value

map:用pair來存(類模板)數據。

map的這個重載括號非常有用

【總結】

1. map中的的元素是鍵值對

2. map中的key是唯一的,并且不能修改

3. 默認按照小于的方式對key進行比較

4. map中的元素如果用迭代器去遍歷,可以得到一個有序的序列

5. map的底層為平衡搜索樹(紅黑樹),查找效率比較高O(log?N)

6. 支持[]操作符,operator[]中實際進行插入查找。

3.4multimap

multimap - C++ Reference

而這個multimap的插入就不會返回pair,顯然也沒有重載[],因為key可以重復,你如果還能返回

引用,返回的是誰的引用呢?(有很多數據冗余的)

3.5改進之前做的題

20. 有效的括號 - 力扣(LeetCode)

class Solution {
public:bool isValid(string s) {stack<char> st;map<char,char> matchMap;matchMap['('] = ')';matchMap['{'] = '}';matchMap['['] = ']';for(auto ch:s){if(matchMap.count(ch)){st.push(ch);}else{if(st.empty()){return false;}if(matchMap[st.top()]==ch){st.pop();           }elsereturn false;}}if(st.empty()){return true;}elsereturn false;}
};

這樣就可以很方便控制比較邏輯?

138. 隨機鏈表的復制 - 力扣(LeetCode)

之前我們用c語言寫過

c語言的思路:

1拷貝節點鏈接到原鏈表的后面

2拷貝節點的random是源節點random指向的節點

3拷貝節點解下來 鏈接成一個新的鏈表 原鏈表恢復

之前就是先處理random指針,通過將拷貝節點放到原節點后面,就可以知道原節點random指針指向的節點的下一個就是拷貝節點random指向的那一個

有了map我們可以將Node*用map存起來

就是用一個map存節點(k)和拷貝節點(v)

那么k->random ==v->random,就可以鏈接上了

這一步很妙(k->random在map里面肯定可以找到拷貝節點的random)

class Solution {
public:Node* copyRandomList(Node* head) {//拷貝節點map<Node*,Node*> matchMap;Node* copyhead=nullptr;Node* copytail=nullptr;Node* cur = head;while(cur){if(copyhead==nullptr){copyhead = copytail = new Node(cur->val);}else{copytail->next = new Node(cur->val);copytail = copytail->next;}matchMap[cur]=copytail;cur = cur->next;}//處理randomcur = head;Node* copy = copyhead;while(cur){if(cur->random ==nullptr){copy->random = nullptr;}else{copy->random = matchMap[cur->random];}cur = cur->next;copy = copy->next;}return copyhead;}};

代碼量大大減少!

349. 兩個數組的交集 - 力扣(LeetCode)

class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {set<int> s1(nums1.begin(),nums1.end());set<int> s2(nums2.begin(),nums2.end());vector<int> v1,v2;vector<int> ret;for(const auto& e:s1){v1.push_back(e);}for(const auto& e:s2){v2.push_back(e);}size_t c1 = 0;size_t c2 = 0;while(c1!=v1.size() && c2!=v2.size()){if(v1[c1]<v2[c2]){c1++;}else if(v1[c1]>v2[c2]){c2++;}else{ret.push_back(v1[c1]);c1++;c2++;}}return ret;}
};

同時還可以求兩個數組的交? 差? 并? 原理都是一樣的?

692. 前K個高頻單詞 - 力扣(LeetCode)

這題一看就是兩個排序,一個是頻率一個是字典序

1 用優先級隊列

2我們用map,k為字典,v為次數,全部入map后,k為唯一的

(1)我們將數據導出來

sort 不能對map排序,因為map不是隨機迭代器(快排里面有三數取中)

(2)數據導出來之后,string是按照字典序排序的 (map中序導出來(注意導出來的是pair))這時候就用sort去按照頻率排序,當然pair里面重載了比較但是他是先比較first的大小再比較second的大小,且升降序是一樣的,這樣就與我們的要求不同了,我們希望頻率是降序,string是升序,而且先比較頻率(second)那么我們可以用仿函數自己控制比較邏輯

還有一點,這里涉及排序的穩定性的問題,就是排序后改不改變其他元素的相對順序,從之前快排的實現我們可以知道,快排是不穩定的,那么排序后就會改變string的相對順序,這里庫里面提供了一個穩定的stable_sort,這個是穩定的可以用

或者我們可以想一個其他的方法

class Solution {
public:struct Greater{//這里我們控制sort的比較邏輯bool operator()(const pair<string,int>& p1,const pair<string,int>& p2){return p1.second>p2.second ||(p1.second==p2.second && p1.first<p2.first);}};vector<string> topKFrequent(vector<string>& words, int k) {map<string,int> countMap;for(const auto& e:words){countMap[e]++;} vector<pair<string,int>> v1;for(const auto &e: countMap){v1.push_back(e);}stable_sort(v1.begin(),v1.end(),Greater());這里注意,我們已經控制比較邏輯,可以用不穩定的sortvector<string> v2;for(size_t i = 0;i<k;i++){v2.push_back(v1[i].first);}return v2;}
};

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/83421.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/83421.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/83421.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【嵌入式開發-RGB 全彩 LED】

嵌入式開發-RGB 全彩 LED ■ RGB 全彩 LED簡介■ 電路設計■ ■ RGB 全彩 LED簡介 RGB 全彩 LED 模塊顯示不同的顏色。 ■ 電路設計 全彩 LED 使用 PA5、 藍色&#xff08;B&#xff09; TIM2_CHN3 PA1、 綠色&#xff08;G&#xff09;TIM2_CHN2 PA2、 紅色&#xff08;R&am…

計算機網絡:手機和基站之間的通信原理是什么?

手機與基站之間的通信是無線通信技術的核心應用之一,涉及復雜的物理層傳輸、協議交互和網絡管理機制。以下從技術原理、通信流程和關鍵技術三個層面深入解析這一過程: 一、蜂窩網絡基礎架構 1. 蜂窩結構設計 基本原理:將服務區域劃分為多個六邊形“蜂窩小區”,每個小區由*…

【Docker】Docker安裝RabbitMQ

目錄 1.拉取鏡像 2. 創建掛載目錄 3.創建和啟動 4.登錄管理端 1.拉取鏡像 推薦使用帶 Web 管理界面的官方鏡像&#xff08;management&#xff09; # 拉取docker鏡像 docker pull rabbitmq:management響應內容&#xff1a; 2. 創建掛載目錄 創建掛載目錄和日志目錄 #rabb…

交叉編譯源碼的方式移植ffmpeg-rockchip

獲取ffmpeg源碼 git submodule add -f https://github.com/FFmpeg/FFmpeg.git thirdparty/FFmpeg 瑞芯微ffmpeg-rk git clone https://github.com/jjm2473/ffmpeg-rk/tree/enc# 參考的一位博主的說法 使用 ffmpeg-rochip 的好處 傳統的使用硬件編解碼的開發思路是&#xf…

9.0 C# 調用solidworks介紹1

一、C# 與 SolidWorks 聯合開發概述 SolidWorks 提供了完整的 API(應用程序接口),允許開發者使用 C# 等編程語言進行二次開發,實現自動化設計、定制功能等。 主要技術要點包括: 1. API 結構:SolidWorks API 是基于 COM 的接口,包含數百個對象和數千個方法…

AD 多層線路及裝配圖PDF的輸出

裝配圖的輸出&#xff1a; 1.點開‘智能PDF’ 2. 設置顯示頂層&#xff1a; 設置顯示底層&#xff1a; 多層線路的輸出 同樣使用‘智能PDF’

SpringBoot + Shiro + JWT 實現認證與授權完整方案實現

SpringBoot Shiro JWT 實現認證與授權完整方案 下面博主將詳細介紹如何使用 SpringBoot 整合 Shiro 和 JWT 實現安全的認證授權系統&#xff0c;包含核心代碼實現和最佳實踐。 一、技術棧組成 技術組件- 作用版本要求SpringBoot基礎框架2.7.xApache Shiro認證和授權核心1.…

PCIe數據采集系統詳解

PCIe數據采集系統詳解 在上篇文章中&#xff0c;廢了老大勁兒我們寫出了PCIe數據采集系統&#xff1b;其中各個模塊各司其職&#xff0c;相互配合。完成了從數據采集到高速存儲到DDR3的全過程。今天我們呢就來詳細講解他們之間的關系&#xff1f;以及各個模塊的關鍵點&#xff…

2025云智算技術白皮書

1. 云智算的演進背景 傳統云計算面臨三大挑戰&#xff1a; 算力需求激增&#xff1a;AI大模型訓練需十萬卡級GPU集群&#xff0c;資源調度能力不足。網絡性能瓶頸&#xff1a;TB級參數同步對低時延、高吞吐要求遠超傳統網絡架構。服務形態單一&#xff1a;IaaS/PaaS無法覆蓋A…

C語言編程中的時間處理

最簡單的time 在C語言編程中&#xff0c;處理時間最簡單的函數就是time了。它的原型為&#xff1a; #include <time.h> time_t time(time_t *_Nullable tloc);返回自從EPOCH&#xff0c;即1970年1月1日的零點零時零分&#xff0c;到當前的秒數。 輸入參數可以是NULL。…

適應性神經樹:當深度學習遇上決策樹的“生長法則”

1st author: Ryutaro Tanno video: Video from London ML meetup paper: Adaptive Neural Trees ICML 2019 code: rtanno21609/AdaptiveNeuralTrees: Adaptive Neural Trees 背景 在機器學習領域&#xff0c;神經網絡&#xff08;NNs&#xff09;憑借其強大的表示學習能力&…

InitVerse節點部署教程

項目介紹: InitVerse 是一個為新興企業量身定制的自動化 Web3 SaaS 平臺,只需單擊幾下即可快速開發和部署 DApp。在 INIChain 和 INICloud 的支持下,InitVerse 可以根據需求動態調整計算資源,實現高效的任務處理,同時提供更高的安全性、可用性和可擴展性。 系統要求: C…

阿里開源通義萬相 Wan2.1-VACE,開啟視頻創作新時代

0.前言 阿里巴巴于2025年5月14日正式開源了其最新的AI視頻生成與編輯模型——通義萬相Wan2.1-VACE。這一模型是業界功能最全面的視頻生成與編輯工具&#xff0c;能夠同時支持多種視頻生成和編輯任務&#xff0c;包括文生視頻、圖像參考視頻生成、視頻重繪、局部編輯、背景延展…

解決“VMware另一個程序已鎖定文件的一部分,進程無法訪問“

問題描述 打開VMware里的虛擬機時&#xff0c;彈出"另一個程序已鎖定文件的一部分&#xff0c;進程無法訪問"如圖所示&#xff1a; 這是VM虛擬機的保護機制。虛擬機運行時&#xff0c;為防止數據被篡改&#xff0c;會將所運行的文件保護起來。當虛擬機崩潰或者強制…

基于大數據的租房信息可視化系統的設計與實現【源碼+文檔+部署】

課題名稱 基于大數據的租房信息可視化系統的設計與實現 學 院 專 業 計算機科學與技術 學生姓名 指導教師 一、課題來源及意義 租房市場一直是社會關注的熱點問題。隨著城市化進程的加速&#xff0c;大量人口涌入城市&#xff0c;導致租房需求激增。傳統的租…

Vue3封裝公共圖片組件

對圖片加載做的處理: 圖片加載狀態響應式管理圖片訪問錯誤的處理機制圖片懶加載可通過slot支持自定義加載動畫其他監聽事件的處理及向上傳遞 …<!-- components/CustomImage.vue --> <template><div class="custom-image-wrapper"><!-- 主圖 -…

車道線檢測----CLRKDNet

今天的最后一篇 車道線檢測系列結束 CLRKDNet&#xff1a;通過知識蒸餾加速車道檢測 摘要&#xff1a;道路車道是智能車輛視覺感知系統的重要組成部分&#xff0c;在安全導航中發揮著關鍵作用。在車道檢測任務中&#xff0c;平衡精度與實時性能至關重要&#xff0c;但現有方法…

Python-感知機以及實現感知機

感知機定義 如果有一個算法&#xff0c;具有1個或者多個入參&#xff0c;但是返回值要么是0&#xff0c;要么是1&#xff0c;那么這個算法就叫做感知機&#xff0c;也就是說&#xff0c;感知機是個算法 感知機有什么用 感知機是用來表示可能性的大小的&#xff0c;我們可以認…

STM32 ADC+DMA+TIM觸發采樣實戰:避坑指南與源碼解析

知識點1【TRGO的介紹】 1、TRGO的概述 TRGO&#xff1a;Trigger Output&#xff08;觸發輸出&#xff09;&#xff0c;是定時器的一種功能。 它可以作為外設的啟動信號&#xff0c;比如ADC轉換&#xff0c;DAC輸出&#xff0c;DMA請求等。 對于ADC來說&#xff0c;可以通過…

Qwen3技術報告解讀

https://github.com/QwenLM/Qwen3/blob/main/Qwen3_Technical_Report.pdf 節前放模型&#xff0c;大晚上的發技術報告。通義&#xff0c;真有你的~ 文章目錄 預訓練后訓練Long-CoT Cold StartReasoning RLThinking Mode FusionGeneral RLStrong-to-Weak Distillation 模型結構…