当前位置: 首页 > news >正文

C++ Primer 第十一章 关联容器 重点解读

1 map自定义排序

#include <map>
#include <iostream>
#include <functional>
using namespace std;
int main() {function<bool(pair<int, int>, pair<int, int>)> cmp = [&](pair<int, int> p1, pair<int, int> p2) -> bool {return p1.second < p2.second;};map< pair<int, int>, int, decltype(cmp)> mp({ {{5, 1}, 2}, {{1, 7}, 3}, {{7, 3}, 2}, {{2, 2}, 1} },cmp);//map<pair<int, int>, int> mp = { {{5, 2}, 2}, {{1, 2}, 3}, {{7, 2}, 2}, {{2, 2}, 1} };for (auto& p : mp) {cout << p.first.first << ' ' << p.first.second << ' ' << p.second << '\n';}
}

map的类模板参数
在这里插入图片描述
map的构造函数
在这里插入图片描述

2 map/unordered_map的下标操作

2.1 at()

访问关键字为k的元素,带参数检查:若k不存在容器中,抛出一个out_of_range异常

2.2 下标运算符与解引用迭代器的区别

下标运算符:调用insert返回pair<iterator, bool>用返回的迭代器访问mapped_type

		V& operator[](const K& key) {pair<iterator, bool> ret = _t.insert(make_pair(key, V()));return ret.first->second;}

解引用迭代器返回pair<key_type, mapped_type>

2.3 对比vector与map的下标运算符

map<int, int> m;
m[0] = 1;vector<int> v;
v[0] = 1;

2.4 对map使用find替代下标操作

使用下标操作有一个严重的副作用:如果关键字还未在map中,下标操作会插入一个具有给定关键字的元素(具体原因可以参考2.2节给出的代码),其值为0;

3 用lower_bound、upper_bound、equal_range查找multimap中的元素

  1. 用lower_bound与upper_bound锁定范围
//authoers的key为作者,mapped为书名
//search_item表示要查找的作者
for (auto beg = authors.lower_bound(search_item), end = authors.upper_bound(search_item); beg != end; ++beg) {cout << beg->second << endl;
}
  1. 用equal_range锁定范围

equal_range接受一个关键字,返回一个迭代器pair,若关键字存在,则第一个迭代器指向第一个与关键字匹配的元素,第二个迭代器指向最后一个匹配元素之后的位置。若未找到匹配元素,则两个迭代器都指向关键字可以插入的位置

for (auto pos = authors.equal_range(search_item); pos.first != pos.second; ++pos.first) {cout << pos.first.second << endl;   
}

4 将自定义类型作为无序容器的关键字

默认情况下,无序容器使用关键字类型的==运算符来比较元素,他们还使用一个hash<key_type>类型的对象(仿函数)来生成每个元素的哈希值。标准库为内置类型(包括指针)提供了hash模板,还为一些标准库类型,比如string和智能指针类型定义了hash。

那么如何定义关键字为自定义类型的无序容器呢?

4.1类模板特化

namespace std {template<>struct hash<Sales_data> {//用来散列一个无需容器的类型必须要定义下列类型typedef size_t result_type;typedef Sales_data argument_type;    //默认情况下,此类型需要operator==size_t operator()(const Sales_data& s) const {return hash<string>() (s.bookNo) ^      //构造匿名对象调用operator()返回一个哈希值hash<unsigned>() (s.units_sold) ^ hash<double>() (s.revenue);}}
}  //关闭std命名空间

4.2 通过类模板传参

size_t hasher(const Sales_data& sd) {return hash<string>() (sd.isbn());
}
//如果类中定义了operator==则只需重载哈希函数
bool eqOp(const Sales_data& lhs, const Sales_data& rhs) {    return lhs.isbn() == rhs.isbn();
}
int main() {using SD_multiset = unordered_multiset<Sales_data, decltype(hahser)*, decltype(eqOp)*>;   //C++11//参数是桶大小、哈希函数指针和相等性判断运算符指针SD_multiset bookstore(42, hasher, eqOp);   
}
  • 为什么能通过上述代码完成自定义类型作为无序容器的关键字呢?
  1. 模板参数

在这里插入图片描述

以下是unordered_multiset类的成员类型,其中key_equal是typedef的第三个模板参数,该类创建的对象用于调用operator==比较两关键字是否相等。

member typedefinitionnotes
key_typethe first template parameter (Key)
mapped_typethe second template parameter (T)
value_typepair<const key_type,mapped_type>
hasherthe third template parameter (Hash)defaults to: hash<key_type>
key_equalthe fourth template parameter (Pred)defaults to: equal_to<key_type>
allocator_typethe fifth template parameter (Alloc)defaults to: allocator<value_type>
referenceAlloc::reference
const_referenceAlloc::const_reference
pointerAlloc::pointerfor the default allocator: value_type*
const_pointerAlloc::const_pointerfor the default allocator: const value_type*
iteratora forward iterator to value_type
const_iteratora forward iterator to const value_type
local_iteratora forward iterator to value_type
const_local_iteratora forward iterator to const value_type
size_typean unsigned integral typeusually the same as size_t
difference_typea signed integral typeusually the same as ptrdiff_t
  1. equal_to类模板的实现:

在这里插入图片描述

equal_to类在容器中创建的对象:key_eq(其他无序容器均有)
在这里插入图片描述
在这里插入图片描述

  1. 对于unordered系列的构造函数,都有一个接受unsigned int参数的构造函数,表示哈希桶的大小,且不能被隐式类型转换
    在这里插入图片描述

5 无序容器的管理操作

  • Buckets
    • bucket_count

      Return number of buckets (public member function)

    • max_bucket_count

      Return maximum number of buckets (public member function)

    • bucket_size

      Return bucket size (public member type)

    • bucket

      Locate element’s bucket (public member function)

    Hash policy
    • load_factor

      Return load factor (public member function)

    • max_load_factor

      Get or set maximum load factor (public member function )

    • rehash

      Set number of buckets (public member function )

    • reserve

      Request a capacity change (public member function)

#include <unordered_map>
#include <iostream>
using namespace std;
int main() {unordered_map<int, int> mp(8);cout << mp.bucket_count() << endl;    //output: 8mp.insert({ 1, 1 });mp.insert({ 2, 1 });mp.insert({ 3, 1 });mp.insert({ 11, 1 });for (int i = 0; i < 8; i++) {cout << mp.bucket_size(i) << ' ';     //output:0 0 0 0 1 0 2 1}
}

6 总结

  • 有序容器(set multiset map multimap)底层为红黑树,使用比较函数来比较关键字,从而将元素按顺序存储。默认情况下,比较操作是采用关键字类型的**<运算符(operator <)**

  • 无序容器(unordered_set unordered_multiset unordered_map unordered_multimap)底层是哈希桶,使用关键字类型的**==运算符(operator ==)和一个hash<key_type>类型的对象来计算哈希值从而组织对象(放入哪个哈希桶中)
    ,使用比较函数来比较关键字,从而将元素按顺序存储。默认情况下,比较操作是采用关键字类型的
    <运算符(operator <)
    *

  • 无序容器(unordered_set unordered_multiset unordered_map unordered_multimap)底层是哈希桶,使用关键字类型的**==运算符(operator ==)**和一个hash<key_type>类型的对象来计算哈希值从而组织对象(放入哪个哈希桶中)

相关文章:

C++ Primer 第十一章 关联容器 重点解读

1 map自定义排序 #include <map> #include <iostream> #include <functional> using namespace std; int main() {function<bool(pair<int, int>, pair<int, int>)> cmp [&](pair<int, int> p1, pair<int, int> p2) -&g…...

MySQL 8 - 能够成功创建其他用户但无法修改 root 用户的密码

问题&#xff1a; 创建其他用户就可以&#xff0c;为什么修改root 密码不可以&#xff1f; 如果能够成功创建其他用户但无法修改 root 用户的密码&#xff0c;这可能是因为 MySQL 8 及更高版本引入了一个名为"caching_sha2_password"的身份验证插件作为默认设置&…...

k8s kubernetes 1.23.6 + flannel公网环境安装

准备环境&#xff0c;必须是同一个云服务厂商&#xff0c;如&#xff1a;华为&#xff0c;阿里、腾讯等&#xff0c;不要存在跨平台安装K8S&#xff0c;跨平台安装需要处理网络隧道才能实现所有节点在一个网络集群中&#xff0c;这里推荐使用同一家云服务厂商安装即可 这里使用…...

博客系统中的加盐算法

目录 一、为什么要对密码进行加盐加密&#xff1f; 1、明文 2、传统的 MD5 二、加盐加密 1、加盐算法实现思路 2、加盐算法解密思路 3、加盐算法代码实现 三、使用 Spring Security 加盐 1、引入 Spring Security 框架 2、排除 Spring Security 的自动加载 3、调用 S…...

同花顺动态Cookie反爬JS逆向分析

文章目录 1. 写在前面2. 请求分析3. Hook Cookie4. 补环境 1. 写在前面 最近有位朋友在大A失意&#xff0c;突发奇想自己闲来无事想要做一个小工具&#xff0c;监测一下市场行情的数据。自己再分析分析&#xff0c;虽是一名程序员但苦于对爬虫领域相关的技术不是特别熟悉。最后…...

异步加载JS的方法

异步加载 JavaScript (JS) 文件是提高网页性能的一种常用技术&#xff0c;这样可以使页面在等待 JS 文件加载和执行时不会阻塞。以下是一些异步加载 JS 的方法&#xff1a; 使用 <script> 标签的 async 属性 通过将 <script> 标签的 async 属性设为 true&#xf…...

IO/NIO交互模拟及渐进式实现

IO IO Server public class SocketServer {public static void main(String[] args) {//server编号和client编号对应&#xff0c;优缺点注释在server端//server1();//server2();server3();}/*** server1的缺点&#xff1a;* 1、accept()方法阻塞了线程&#xff0c;要等客户端…...

springboot+html实现密码重置功能

目录 登录注册&#xff1a; 前端&#xff1a; chnangePssword.html 后端&#xff1a; controller: Mapper层&#xff1a; 逻辑&#xff1a; 登录注册&#xff1a; https://blog.csdn.net/m0_67930426/article/details/133849132 前端&#xff1a; 通过点击忘记密码跳转…...

LeetCode 2525. 根据规则将箱子分类【模拟】1301

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…...

atcoder [Road of the King] 题解(DP好题)

题面 简要题意&#xff1a;有一个 n n n 个点的图&#xff0c;目前一条边都没有。有一个人在 1 1 1 号点要进行 m m m 次移动&#xff0c; 终点不必是 1 1 1 号点。加入第 i i i 次的从 u u u 移动到了 v v v&#xff0c; 那么 u u u 到 v v v 之间出现一条有向边。问…...

CImageList 图像列表

一、CImageList类Create函数参数解析 BOOL Create(int cx,int cy,UINT nFlags,int nInitial,int nGrow ); 1.1&#xff09; cx,cy&#xff1a;图片的实际像素宽与高&#xff1b; nFlags&#xff1a;创建图像列表的类型,包括4/8/16/24/32/位色&#xff1b; nFlags确定建立图…...

【OpenGL】四、坐标系统和摄像机

坐标转换 文章目录 坐标转换坐标系统的转换局部空间(Local Space&#xff09;->世界空间(World Space)世界空间(World Space)->观察空间&#xff08;View Space/View Space&#xff09;裁剪空间(Clip Space)MVP矩阵 坐标系统的转换 了解坐标系统和空间变换之前需要先了解…...

使用vcpkg管理依赖第三库

文章目录 使用vcpkg管理依赖第三库vcpkg安装vcpkg经典模式使用从仓库列表搜索依赖项从某个基线版本的列表中查询某个依赖项信息安装依赖库 vcpkg清单模式的使用vcpkg清单模式的使用例子说明 使用vcpkg管理依赖第三库 vcpkg 有两种操作模式&#xff1a;经典模式和清单模式。 在…...

Android渲染一个列表的过程,并提供动态改变样式

1、index.xml 布局文件&#xff0c;我省略了其他代码&#xff0c;我们需要recyclerview保证在规定范围内&#xff0c;如果列表元素过多可以滑动 <LinearLayoutandroid:layout_width"match_parent"android:layout_height"match_parent"android:layout_…...

Leetcode—260.只出现一次的数字III【中等】

2023每日刷题&#xff08;三&#xff09; Leetcode—260.只出现一次的数字III 借助lowbit的解题思想 参考的灵茶山艾府大神的题解 实现代码 /*** Note: The returned array must be malloced, assume caller calls free().*/ int* singleNumber(int* nums, int numsSize, in…...

Mysql 约束,基本查询,复合查询与函数

文章目录 约束空属性约束默认值约束zerofill主键约束自增长约束唯一键约束外键约束 查询select的执行顺序单表查询排序 updatedelete整张表的拷贝复合语句group by分组查询 函数日期函数字符串函数数学函数其他函数 复合查询合并查询union 约束 空属性约束 两个值&#xff1a…...

web前端基础CSS------美化页面“footer”部分

一&#xff0c;实验代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>关于我们</title><style type"text/css">#footer{margin: 10px 0px;background: #f5f5f5;border: top 1px solid #eee ;}#f…...

在中国,技术到底有多有用?

&#x1f64c;秋名山码民的主页 &#x1f602;oi退役选手&#xff0c;Java、大数据、单片机、IoT均有所涉猎&#xff0c;热爱技术&#xff0c;技术无罪 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; 获取源码&#xff0c;添加WX 目录 前言1.…...

《动手学深度学习 Pytorch版》 9.2 长短期记忆网络(LSTM)

解决隐变量模型长期信息保存和短期输入缺失问题的最早方法之一是长短期存储器&#xff08;long short-term memory&#xff0c;LSTM&#xff09;。它与门控循环单元有许多一样的属性。长短期记忆网络的设计比门控循环单元稍微复杂一些&#xff0c;却比门控循环单元早诞生了近 2…...

计算机操作系统-第十一天

目录 1、进程的状态 创建态与就绪态 运行态 终止态 新建态 结束态 进程状态的转换 进程的组织方式 链接方式&#xff08;常见&#xff09; 索引方式&#xff08;少见&#xff09; 本节思维导图 1、进程的状态 创建态与就绪态 1、进程正在被创建时&#xff0c;处于…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...