C++中的關聯容器

文章目錄

  • 使用關聯容器
  • 定義關聯容器
    • 關鍵字類型的要求
    • pair類型
    • 用作返回類型
  • 關聯容器上的操作
    • 關聯容器的迭代器
    • 關聯容器和算法
    • 添加元素
    • 刪除元素
    • map的下標操作
    • 訪問元素
  • 無序容器
    • 對關鍵字的要求

關聯容器支持高效的關鍵字查找和訪問。兩個主要的關聯容器的類型是map和set。其中map中的元素是一些關鍵字-值(key-value)對。set中每個元素只包含一個關鍵字。

標準庫中提供8個關聯容器。分別體現在3個維度上:

  • 每種容器要么是map,要么是set;
  • 是否允許存在重復的關鍵字,允許重復通常以multi開頭;
  • 是否有序,無序通常以unordered開頭;

因此unorderd_multiset是一個允許重復的無序集合。set則是一個要求不重復的有序集合。
在這里插入圖片描述

使用關聯容器

統計輸入的單詞出現次數,并剔除一些不重要的詞匯。

map<string, size_t> wordCount;
set<string> exclude = {"the", "but", "and", "or", "an", "a"};string word;
while(cin >> word)
{if(exclude.find(word) == exclude.end())map[word]++;
}

定義關聯容器

map<string, string> authors = {{"key", "value"}, {{"key", "value"}, {{"key", "value"}}; //初始化一個map時,必須提供key, value并包含在花括號中。//定義一個包含20個元素的vec,保持0-9每個整數的兩個拷貝
vector<int> ivec;
for(vector<int>::size_type i = 0; i < 10; ++i)
{ivec.push_back(i);ivec.push_back(i);
}set<int> iset(ivec.begin(), ivec.end()); //size = 10;
multiset<int> miset(ivec.begin(), ivec.end()); //size = 20;

關鍵字類型的要求

對于有序容器,關鍵字的類型必須定義元素比較的方法。默認情況下關鍵字類型的<運算符來比較兩個關鍵字。也可以提供自定義的比較操作:

bool compareIsbn(const Sales_data & lhs, const Sales_data &rhs)
{return lhs.isbn() < rhs.isbn();
}multiset<Sales_data, decltype(compareIsbn)*> bookstore(compareIsbn);

為了定義自己的操作,在定義multiset的時候,必須提供兩個類型:關鍵字類型以及比較操作類型(函數指針類型)。這里使用decltype來獲得函數指針類型。對象初始化的時候還得傳入比較函數指針。

pair類型

pair的默認構造函數對數據成員進行值初始化。map的元素是pair。
在這里插入圖片描述

用作返回類型

pair<string, int> process(vector<string> &v)
{if(!v.empty()){return {v.back(), v.back().size()}; //列表初始化}else{return pair<string, int>(); //隱式構造返回值,make_pair("", 0);}
}

關聯容器上的操作

在這里插入圖片描述

set<string>::key_type v1; //string
set<string>::value_type v2; //string
map<string, int>::key_type v3; //string
map<string, int>::mapped_type v4; //int
map<string, int>::value_type v5; //pair<const string, int>

關聯容器的迭代器

解引用一個關聯容器的迭代器時,會得到一個類型為容器的value_type的值的引用。*

  • map對應一個pair類型,其first保存const關鍵字,second保存值;
  • set雖然同時定義了iterator和const_iterator,但兩種類型都只允許讀set中的元素,都是const屬性的。
auto map_it = word_count.cbegin();
while(map_it != word_count.cend())
{cout << map_it->first << map_it->second << endl;++map_it;
}

因為其實有序的,因此這里打印輸出也是有序的。

關聯容器和算法

通常不對關聯容器使用泛型算法。鍵的const的屬性不適用于大多數泛型算法。

添加元素

在這里插入圖片描述
有序容器中,insert(p, v)其中p只是一個hint,不一定有效。
insert或emplace的返回值依賴于容器類型何參數。對于不包含重復關鍵字的容器,添加單一元素會返回一個pair,其first成員是一個迭代器,指向給定關鍵字的元素;second成員是一個bool,表示元素是否插入(若關鍵字已經存在,則不插入)。

  • set:對于一個給定的關鍵字,只有第一個帶此關鍵字的元素被插入到容器中
vector<int> ivec = {2, 4, 6, 8, 2, 4, 6, 8};
set<int> set2;
set2.insert(ivec.begin(), ivec.end()); //4個元素
set2.insert({2, 4, 6, 8}); //4個元素
  • map
word_count.insert({word, 1});
word_count.insert(make_pair(word, 1));
word_count.insert(pair<string, int>(word, 1));
word_count.insert(map<string, int>::value_type(word, 1));
  • multimap、multiset:關鍵字允許重復,因此插入操作總會插入元素。即時接受單個元素的插入操作,也只會返回一個指向該元素的迭代器。

刪除元素

在這里插入圖片描述

map的下標操作

在這里插入圖片描述

訪問元素

在這里插入圖片描述
其中lower_bound、upper_bound、equal_range只適用于有序容器。

有這么一個應用場景,打印輸出一個作者的所有書籍,數據存儲在一個multimap中。可以通過以下三種方式實現:

string search_item("Alain de Botton");
//1
auto entries = authors.count(search_item);
auto iter = authors.find(search_item);
while(entries)
{cout << iter->second << endl;entries--;iter++;
}//2
for(auto beg = author.lower_bound(search_item), end = author.upper_bound(search_item); beg != end; beg++)cout << iter->second << endl;//3
for(auto pos = authors.equal_range(search_item); pos.first != pos.second; pos.first++)cout << pos.first->second << endl;

無序容器

無序容器使用hash函數和關鍵字類型的==來組織元素。其在存儲上組織為一組桶,使用hash函數將元素映射到桶。為了訪問一個元素,容器首先計算元素的hash值,它指出該搜索哪個桶。當一個桶中包含多個元素時,需要順序搜索這些元素值來找到我們想要的那個。

無序容器提供了一組管理桶的函數:
在這里插入圖片描述

對關鍵字的要求

對于內置類型、string、智能指針等可以直接當作關鍵字。當要把自定義類型作為關鍵字時,需要提供自定義的hash、和==函數。

size_t hasher(const Sales_data &sd)
{return hash<string>()(sd.isbn());
}
bool eqOp(const Sales_data &lhs, const Sales_data &rhs)
{return lhs.isbn() == rhs.isbn();
}using SD_multiset = unordered_multiset<Sales_data, decltype(hasher)*, decltype(eqOp)*>;//參數桶大小,hash,==
SD_multiset bookstore(42, hasher, eqOp);

如果類定義了==運算符,則可以只重載hash函數:

#include <iostream>
#include <unordered_map>struct Point {int x;int y;// 相等比較:unordered_map 要求bool operator==(const Point& other) const {return x == other.x && y == other.y;}
};// 自定義哈希函數
struct PointHash {std::size_t operator()(const Point& p) const {return std::hash<int>()(p.x) ^ (std::hash<int>()(p.y) << 1);}
};int main() {std::unordered_map<Point, std::string, PointHash> umap;umap[{1, 2}] = "A";umap[{3, 4}] = "B";umap[{1, 2}] = "C"; // 會覆蓋前面的 "A"for (const auto& pair : umap) {std::cout << "(" << pair.first.x << "," << pair.first.y << ") = "<< pair.second << '\n';}
}

其中std::hash<int>()創建一個臨時對象,std::hash<int>()()調用該對象。

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

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

相關文章

【Git】git提交代碼報錯Git: husky > pre-commit

git提交代碼報錯原因 這個問題是因為當你在終端輸入git commit -m “XXX”,提交代碼的時候,pre-commit(客戶端)鉤子&#xff0c;它會在Git鍵入提交信息前運行做代碼風格檢查。如果代碼不符合相應規則&#xff0c;則報錯&#xff0c;而它的檢測規則就是根據.git/hooks/pre-commi…

Unity開發者快速認識Unreal 的C++(六)GameMode之PlayerController

繼承關系&#xff1a;Aactor&#xff0c;INavAgentInterface <--- AController<--- PlayerController &#xff0c;PlayerController也是一個Actor,繼承了Actor的一些通用的屬性和工具函數下圖是PlayerController初始化組件的一個子階段從圖中可以得到的信息是&#xf…

Vue 3 服務端渲染(SSR)與客戶端渲染(CSR)的區別及解決方案

1. SSR與CSR的區別1.1. SSR的原理服務端渲染&#xff08;SSR&#xff09;是在服務器端將 Vue 組件渲染為 HTML 字符串&#xff0c;并將其發送給客戶端。這種方式與客戶端渲染&#xff08;CSR&#xff09;不同&#xff0c;后者是在瀏覽器中執行 JavaScript 來生成 HTML。在 SSR …

Matlab快速回顧

一1.數值 顯示 格式format style 設置eg: pi format longE;or2.清除指令clc 清除命令行窗口clear 清除工作區cls3.搜索路徑設置path(path,E:\ads\)oraddpath4.M文件用戶把要實現的命令寫在一個以.m為擴展的文件中&#xff0c;然后由matlab系統進行解讀&#xff0c;最后運行結果…

開源低代碼+AI引擎:百特搭企業級開發平臺的演進

在數字化轉型進入深水區的今天&#xff0c;企業應用開發面臨前所未有的復雜挑戰&#xff1a;既要快速響應業務需求&#xff0c;又要確保系統靈活可控&#xff1b;既要降低技術門檻&#xff0c;又要保障核心安全。傳統開發模式與單一形態的低代碼工具已難以滿足多層次需求。融合…

學習 Android(十五)NDK進階及性能優化

學習 Android&#xff08;十五&#xff09;NDK進階及性能優化 對 NDK 相關知識有了初步的了解之后&#xff0c;我們可以更加深入的去學習 NDK 相關知識&#xff0c;接下來&#xff0c;我們將按照以下步驟進行深入學習&#xff1a; 深入理解JNI調用過程和性能消耗常見 JNI 坑&am…

QT5.12.8 QTabWidget 透明樣式QSS

/* 設置QTabWidget本身 :不加也行*/ QTabWidget#aaa_tabwdt {background: transparent;border: none; /* 移除邊框可能有助于透明效果 */ }/* 標簽頁內的容器部件 :必須加&#xff0c;標簽也才會透明 */ QTabWidget#aaa_tabwdt QWidget, QTabWidget#aaa_tabwdt QFrame {backgro…

【FAQ】Script導出SharePoint 目錄文件列表并統計大小

一、只導出文件列表的方法 1) 保存腳本&#xff08;建議名&#xff1a;D:\tmp\Export-SharePoint-FileList.ps1&#xff09; <# 導出 SharePoint 指定文件夾&#xff08;含子文件夾&#xff09;的文件列表到 CSV&#xff08;不統計大小&#xff09; 前提&#xff1a;已安…

《Thinking in Java》讀書筆記---控制執行流程

就像有感知的生物一樣&#xff0c;程序必須在執行過程中控制它的世界&#xff0c;并做出選擇。在Java中&#xff0c;你要使用執行控制語句來作出選擇。一、流程控制基礎概念1.1 流程控制的重要性流程控制結構決定了程序執行的順序和邏輯分支&#xff0c;是編程語言中最基礎也是…

極驗 G-star 人才特訓營:為業務安全領域培養下一代新興力量

本文導讀 極驗為什么要啟動 G-star 實習生培養計劃&#xff1f;50多位來自多所高校的同學&#xff0c;在極驗經歷了一場怎樣的“非典型”實習&#xff1f;技術大咖親授&#xff0c;先培訓再實戰&#xff0c;極驗打造的是怎樣的人才體系&#xff1f;同學有話說&#xff1a;培養計…

攻防世界-web-csaw-mfw

一.題目分析這邊提示使用了Git&#xff0c;試著訪問.git看是否存在.git泄露瀏覽了一下&#xff0c;很多都是亂碼&#xff0c;想著用githack將git庫克隆下看一下二.操作python2 GitHack.py http://url/.git訪問了一下flag.php&#xff0c;沒啥發現&#xff0c;在看一下index.php…

202506 電子學會青少年等級考試機器人四級實際操作真題

更多內容和歷年真題請查看網站&#xff1a;【試卷中心 -----> 電子學會 ----> 機器人技術 ----> 四級】 網站鏈接 青少年軟件編程歷年真題模擬題實時更新 2025年6月 青少年等級考試機器人實操真題四級 實際操作 主題&#xff1a;感應節能燈&#xff08;四級&am…

DLT645電表數據 保存到MySQL數據庫項目案例

目錄 1 案例說明 2 VFBOX網關工作原理 3 準備工作 4 配置VFBOX網關采集DLT645電表數據 5 網關寫數據到MYSQL數據庫 6 安裝MYSQL數據庫 7 其他說明 8 案例總結 1 案例說明 設置網關采集DLT645電表數據數據把采集的數據保存到MySQL數據庫。 2 VFBOX網關工作原理 VFBOX網關…

Redux與React - 異步狀態操作(React快速上手4)

異步操作樣板代碼1. 創建store的寫法保持不變&#xff0c;配置好同步修改狀態的方法 2. 單獨封裝一個函數&#xff0c;在函數內部return一個新函數&#xff0c;在新函數中 2.1 封裝異步請求獲取數據 2.2 調用同步actionCreater傳入異步數據生成一個action對象&#xff0c;并使用…

win10桌面右鍵沒有新建word

win10右鍵新建word不見解決方法1、點擊開始&#xff0c;找到運行命令行&#xff0c;輸入regedit&#xff0c;打開注冊表。2、在左側找到HKEY_CLASSES_ROOT目錄&#xff0c;并展開。3.找到.docx 雙擊&#xff08;默認&#xff09;一項&#xff0c;將其改為 Word.Document.12。關…

Docker國內可用鏡像(2025.08.06測試)

Docker渡渡鳥鏡像可用&#xff08;測試時間2025.08.06&#xff09;https://docker.aityp.com/使用渡渡鳥鏡像pull ollama latest 例子&#xff1a;docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/ollama/ollama:0.10.1毫秒鏡像和軒轅鏡像也可用&#xff0c;但…

決策樹的實際案例

決策樹作為一種直觀、易解釋的機器學習算法&#xff0c;在金融、醫療、電商、風控等多個領域都有廣泛的實際應用。以下將講解1個典型案例&#xff1a;貸款違約預測。對于貸款違約預測&#xff0c;即在貸款人員在貸款之前對其進行預測&#xff0c;通過他的眾多特征情況判別是否可…

bool 類型轉換運算符重載

以下是一個極簡且聚焦核心知識點的示例代碼&#xff0c;用最直觀的方式演示 bool 類型轉換運算符重載的觸發邏輯、使用場景和避坑點&#xff0c;幫你快速掌握&#xff1a;cpp運行#include <iostream> using namespace std;// 核心類&#xff1a;演示 bool 轉換運算符 cla…

LVGL代碼框架簡介

LVGL代碼框架介紹LVGL&#xff08;Light and Versatile Graphics Library&#xff09;是一個輕量級、功能強大的嵌入式圖形庫。其代碼架構設計清晰&#xff0c;模塊化程度高。1. 整體架構層次LVGL采用分層架構設計&#xff0c;主要包含以下幾個層次&#xff1a;┌───────…

【云計算】云主機的親和性策略(三):云主機 宿主機

《云主機的親和性策略》系列&#xff0c;共包含以下文章&#xff1a; 1?? 云主機的親和性策略&#xff08;一&#xff09;&#xff1a;快樂旅行團2?? 云主機的親和性策略&#xff08;二&#xff09;&#xff1a;集群節點組3?? 云主機的親和性策略&#xff08;三&#xf…