c++ stl multimap&unordered_multimap

容器對比說明圖

廢話不多說,先上圖。no picture say jb..


容器對比說明圖.png
前言

日常工作中常用的std容器一般vector、list、queue、map,對于multimap此類很少用到。(主要沒有遇到合適的場景,可能我太菜)

嘗試使用

multimap與unordered_multimap常用于'多對多'場景下,那么什么樣的多對多呢,我百度了一圈也沒見有人舉例。根據(jù)multimap的主要特性,“key可以重復(fù)”我們來舉個(gè)簡單點(diǎn)的栗子,比如我們需要將一個(gè)年級的學(xué)生都存到一個(gè)multimap中,大概就會(huì)是以下這個(gè)樣子。
假設(shè)我們有這樣的一個(gè)結(jié)構(gòu):

typedef struct {
    int mID_;
    int mAge_;
    string mName_;
}StudentInfo;

假設(shè)這個(gè)年級有三個(gè)班,那數(shù)據(jù)可能以下面的這個(gè)樣子:

/*引入頭文件*/
#include<unordered_map>
/*定義學(xué)生*/
StudentInfo studentA = { 50, 16, "NameA" };
StudentInfo studentB = { 100, 17, "NameB" };
StudentInfo studentC = { 150, 16, "NameC" };
/*定義multimap,類型名字太長,使用別名*/
using StudentMultiMap = std::unordered_multimap<string/*班級*/, StudentInfo/*學(xué)生信息*/>;
StudentMultiMap allStudent;
/*對學(xué)生進(jìn)行存儲*/
//如果使用key無重復(fù)的則如此
allStudent.insert(std::make_pair("一班", studentA));
allStudent.insert(std::make_pair("二班", studentB));
allStudent.insert(std::make_pair("三班", studentC));
//如果key有重復(fù),實(shí)際情況下,每個(gè)班有多個(gè)同學(xué)
allStudent.insert(std::make_pair("一班", studentD));
allStudent.insert(std::make_pair("一班", studentE));
allStudent.insert(std::make_pair("一班", studentF));
multimap和unordered_multimap常用函數(shù)
//insert  插入一個(gè)對象
  allStudent.insert(std::make_pair("一班", studentG));
//size 返回multimap中的對象個(gè)數(shù)
  allStudent.size(); 
//empty 判斷是否為空
  allStudent.empty(); 
//count 統(tǒng)計(jì)某個(gè)key的對象個(gè)數(shù)
  allStudent.count("一班");
//find根據(jù)key查找對象,返回遍歷到的第一個(gè)使用該key迭代器
  StudentMultiMap::iterator tmp = allStudent.find("二班");
//contains c++20才開始支持
  allStudent.contains("三班");  //返回bool值,判斷是否擁有使用該key的對象

以下這兩個(gè)函數(shù)unordered_multimap是沒有的?。?!
單獨(dú)說明一下,對key進(jìn)行hash以后,在multimap中key的順序可能是:
 一班(0),一班(1),二班(2),二班(3),三班(4),三班(5),//這是只是為了形象展示
如果對一班進(jìn)行l(wèi)ower_bound,那lower的iterator指向:0,而upper則指向:2 
//lower_bound  返回指向首個(gè)不小于給定鍵的元素的迭代器 
  StudentMultiMap::iterator lower = allStudent.lower_bound("一班");
//upper_bound 返回指向首個(gè)大于給定鍵的元素的迭代器 
  StudentMultiMap::iterator upper = allStudent.upper_bound("一班");

//erase刪除指定key,或刪除某一個(gè)迭代器
  allStudent.erase(tmp);//刪除tmp迭代器所指像的對象-單個(gè)
  allStudent.erase("二班");//刪除所有key為'二班'的對象-多個(gè)
  allStudent.erase(lower, upper);//刪除lower~upper這個(gè)區(qū)間-范圍
//equal_range 返回一個(gè)由lower和upper組成的pair
  std::pair<StudentMultiMap::iterator, StudentMultiMap::iterator> stuRange = allStudent.equal_range("一班");
  for (auto& it = stuRange.first; it != stuRange.second; it++) {
    std::cout << it->second.mID_ << ":" << it->second.mAge_ << ":" << it->second.mName_ << std::endl;
  }
//幾個(gè)迭代器,就不單獨(dú)說明了
begin
end
cbegin
cend
//清空multimap
clear
幾種對multimap遍歷的方式
1、auto臨時(shí)變量
for (const auto& tmp : allStudent) {
   std::cout << tmp.second.mID_ << ":" << tmp.second.mAge_ << ":" << tmp.second.mName_ << std::endl;
}
2、原始for
const auto& end = allStudent.end();
for (StudentMultiMap::iterator tmp = allStudent.begin(); tmp != end ; tmp++) {
   std::cout << tmp->second.mID_ << ":" << tmp->second.mAge_ << ":" << tmp->second.mName_ << std::endl;
}

回到使用場景

這種'多對多'的場景,使用multimap還是很好的。
1、像需要對流量進(jìn)行解析時(shí),需要對一個(gè)session所有包都關(guān)聯(lián)起來的時(shí)候,使用IP五元組做為key每個(gè)包做value
2、像對用戶的好友列表?
3、像用戶的購物車?
4、像配置文件?
等等等等吧,反正。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容