C++ STL(五) 无序关联容器

目录

1、std::unordered_set

构造函数

迭代器

迭代器失效

容量操作

修改

查找

桶操作

哈希策略

code示例

2、std::unordered_map

构造函数

元素访问

容量操作

修改

查找

桶、哈希操作

code示例

3、std::unordered_multiset

4、unordered_multimap


1、std::unordered_set

C++ 标准模板库(STL)中的一个无序关联容器,用于存储唯一元素。它基于哈希表实现,支持快速的插入、删除和查找操作。既然底层是哈希表那么常见的哈希问题 哈希函数:将元素映射到哈希表的桶(bucket)中。冲突解决:使用链地址法(Separate Chaining)或开放地址法(Open Addressing)解决哈希冲突。动态扩容:当元素数量超过负载因子(load factor)时,哈希表会自动扩容。

构造函数

unordered_set()默认构造函数,创建一个空的 unordered_set
unordered_set(const unordered_set& other)拷贝构造函数
unordered_set(initializer_list<T> init)使用初始化列表创建 unordered_set

迭代器

begin(), end(): 返回指向第一个元素和最后一个元素之后位置的迭代器。

cbegin(), cend(): 返回常量迭代器

迭代器失效

erase:删除元素时指向被删除元素的迭代器失效。rehash:重新哈希时,所有迭代器失效。

insert:插入元素不会使其他迭代器失效。

容量操作

empty(): 判空。size(): 求元素数量。max_size(): 返回 unordered_set 可以容纳的最大元素数量

修改

clear(): 清除 unordered_set 中的所有元素。    insert(const T& value): 插入元素。

erase(iterator pos): 删除指定位置pos处元素。erase(const T& value): 删除值为value的元素

swap(unordered_set& other): 交换两个 unordered_set 的内容

查找

find(const T& value): 返回指向值为 value 的元素的迭代器,如果未找到则返回 end()
count(const T& value): 返回值为 value 的元素的数量(对于 unordered_set,结果为 0 或 1)
equal_range(const T& value): 返回一个包含 lower_bound 和 upper_bound 的 pair

桶操作

bucket_count(): 返回桶的数量。    bucket_size(size_type n): 返回第 n 个桶中的元素数量。

bucket(const T& value): 返回值为 value 的元素所在的桶的索引。

哈希策略

max_load_factor(): 返回最大负载因子。rehash(size_type n): 设置桶的数量为至少 n。

reserve(size_type n): 预留至少 n 个元素的存储空间; load_factor(): 返回当前负载因子

code示例

#include <iostream>
#include <unordered_set>

int main() {
    //构造
    std::unordered_set<int> us1; // 空 unordered_set
    std::unordered_set<int> us = {1, 2, 3, 4, 5}; // 使用初始化列表创建 unordered_set

    //元素访问
    for (int i : us) {
        std::cout << i << " "; // 输出: 5 4 3 2 1(顺序不确定)
    }
    std::cout << std::endl;
    for (auto it = us.begin(); it != us.end(); ++it) {
        std::cout << *it << " "; // 输出: 5 4 3 2 1(顺序不确定)
    }
    //容量
    std::cout << "us.empty(): " << us.empty() << std::endl; // 输出: 0 (false)
    std::cout << "us.size(): " << us.size() << std::endl;   // 输出: 5
    std::cout << "us.max_size(): " << us.max_size() << std::endl; // 输出: 一个很大的数
    //修改
    us.insert(6); // 插入新元素
    us.emplace(7);
    us.erase(2);  // 删除值为 2 的元素   (7 6 5 4 3 1)
    //us.clear();  清空集合
    
    //查找
    auto it = us.find(3);
    if (it != us.end()) {
        std::cout << "Found: " << *it << std::endl; // 输出: Found: 3
    }
 
    std::cout << "us.count(3): " << us.count(3) << std::endl; // 输出: 1
    std::cout << "us.count(6): " << us.count(6) << std::endl; // 输出: 0

    auto range = us.equal_range(3);
    if (range.first != range.second) {
        std::cout << "Equal range: " << *range.first << std::endl; // 输出: 3
    } else {
        std::cout << "No range found." << std::endl;
    }
    //桶操作
    std::cout << "Bucket count: " << us.bucket_count() << std::endl; // 输出: 桶的数量
    std::cout << "Bucket size for bucket 0: " << us.bucket_size(0) << std::endl; // 输出: 第 0 个桶中的元素数量
    std::cout << "Bucket for value 3: " << us.bucket(3) << std::endl; // 输出: 值为 3 的元素所在的桶的索引
    //哈希操作
    std::cout << "Load factor: " << us.load_factor() << std::endl; // 输出: 当前负载因子
    std::cout << "Max load factor: " << us.max_load_factor() << std::endl; // 输出: 最大负载因子
    us.rehash(10); // 设置桶的数量为至少 10
    us.reserve(20); // 预留至少 20 个元素的存储空间
    return 0;
}

2、std::unordered_map

std::unordered_map是 C++ 标准模板库(STL)中的一个无序关联容器,用于存储键值对(key-value pairs)。它基于哈希表实现,支持快速的插入、删除和查找操作,同样具有哈希的一些特性

构造函数

unordered_map():   默认构造函数,创建一个空的 unordered_map
unordered_map(const unordered_map& other):   拷贝构造函数
unordered_map(initializer_list<std::pair<const Key, T>> init):   使用初始化列表创建 unordered_map

元素访问

operator[](const Key& key):  返回键为 key 的值的引用,如果键不存在则插入一个默认值

at(const Key& key):  返回键为 key 的值的引用,如果键不存在则抛出 std::out_of_range 异常

容量操作

empty(): 判空。size(): 求键值对数量。max_size(): 返回可以容纳的最大键值对数量

修改

  •     clear(): 清除 unordered_map 中的所有键值对。
  •     insert(const std::pair<const Key, T>& value): 插入键值对。
  •     erase(iterator pos): 删除指定位置 pos 处的键值对。
  •     erase(const Key& key): 删除键为 key 的键值对。
  •     swap(unordered_map& other): 交换两个 unordered_map 的内容。

查找

  • find(const Key& key): 返回指向键为 key 的键值对的迭代器,如果未找到则返回 end()
  • count(const Key& key): 返回键为 key 的键值对的数量(对于 unordered_map结果为 0 或 1)
  • equal_range(const Key& key): 返回一个包含 lower_bound 和 upper_bound 的 pair

桶、哈希操作

与unordered_set类似,只有bucket(const Key& key): 返回键为 key 的键值对所在的桶的索引

code示例

#include <iostream>
#include <unordered_map>

int main() {
    std::unordered_map<int, std::string> um1; // 空 unordered_map
    std::unordered_map<int, std::string> um = {{1, "one"}, {2, "two"}, {3, "three"}}; // 使用初始化列表创建 unordered_map
    
    //元素访问
    std::cout << "um[2]: " << um[2] << std::endl; // 输出: two
    std::cout << "um.at(3): " << um.at(3) << std::endl; // 输出: three
    um[4] = "four"; // 插入新键值对
    std::cout << "um[4]: " << um[4] << std::endl; // 输出: four
   
    //容量
    std::cout << "um.empty(): " << um.empty() << std::endl; // 输出: 0 (false)
    std::cout << "um.size(): " << um.size() << std::endl;   // 输出: 4
    std::cout << "um.max_size(): " << um.max_size() << std::endl; // 输出: 一个很大的数
    
    um.insert({5, "five"}); // 插入新键值对
    um.erase(2); // 删除键为 2 的键值对

    auto it = um.find(3);
    if (it != um.end()) {
        std::cout << "Found: " << it->second << std::endl; // 输出: Found: three
    }

    std::cout << "um.count(2): " << um.count(2) << std::endl; // 输出: 0
    std::cout << "um.count(4): " << um.count(4) << std::endl; // 输出: 1

    auto range = um.equal_range(2);
    if (range.first != range.second) {
        std::cout << "Equal range: " << range.first->second << std::endl; 
    } else {
        std::cout << "No range found." << std::endl;  //No range found
    }

    std::cout << "Bucket count: " << um.bucket_count() << std::endl; // 输出: 桶的数量
    std::cout << "Bucket size for bucket 0: " << um.bucket_size(0) << std::endl; // 输出: 第 0 个桶中的键值对数量
    std::cout << "Bucket for key 2: " << um.bucket(2) << std::endl; // 输出: 键为 2 的键值对所在的桶的索引
    std::cout << "Load factor: " << um.load_factor() << std::endl; // 输出: 当前负载因子
    std::cout << "Max load factor: " << um.max_load_factor() << std::endl; // 输出: 最大负载因子

    um.rehash(10); // 设置桶的数量为至少 10
    um.reserve(20); // 预留至少 20 个键值对的存储空间
    return 0;
}

3、std::unordered_multiset

特性unordered_setunordered_multiset
元素唯一性只允许存储唯一元素允许存储重复元素
插入操作如果元素已存在,插入操作不会成功可以插入多个相同的元素
查找元素使用 count() 返回 0 或 1使用 count() 返回元素的出现次数
内存开销通常较小,因为只存储唯一元素可能稍大,因为需要存储重复元素
适用场景适用于需要唯一元素的场景,如集合运算适用于需要重复元素的场景,如频率统计
迭代器迭代器指向唯一元素迭代器可以指向重复元素
性能插入、查找、删除操作平均时间复杂度 O(1)插入、查找、删除操作平均时间复杂度 O(1)
元素访问通过迭代器访问唯一元素通过迭代器访问所有元素,包括重复元素
#include <iostream>
#include <unordered_set>

int main() {
    // 1. 创建 unordered_multiset
    std::unordered_multiset<int> myMultiSet;

    // 2. 插入元素
    myMultiSet.insert(1);
    myMultiSet.insert(2);
    myMultiSet.insert(2); // 插入重复元素
    myMultiSet.insert(3);
    myMultiSet.insert(1); // 再次插入 1

    // 3. 输出元素
    std::cout << "unordered_multiset 中的元素: ";
    for (const auto& item : myMultiSet) {
        std::cout << item << " "; // 输出所有元素,包括重复元素
    }
    std::cout << std::endl;

    // 4. 查找元素
    auto it = myMultiSet.find(2);
    if (it != myMultiSet.end()) {
        std::cout << "找到元素 2" << std::endl;
    } else {
        std::cout << "未找到元素 2" << std::endl;
    }

    // 5. 计数元素
    std::cout << "元素 1 的出现次数: " << myMultiSet.count(1) << std::endl; // 输出 2
    std::cout << "元素 2 的出现次数: " << myMultiSet.count(2) << std::endl; // 输出 2
    std::cout << "元素 4 的出现次数: " << myMultiSet.count(4) << std::endl; // 输出 0

    // 6. 删除元素
    myMultiSet.erase(2); // 删除一个 2
    std::cout << "删除一个 2 后的元素: ";
    for (const auto& item : myMultiSet) {
        std::cout << item << " "; // 输出剩余元素
    }
    std::cout << std::endl;

    // 7. 删除所有指定元素
    myMultiSet.erase(1); // 删除所有 1
    std::cout << "删除所有 1 后的元素: ";
    for (const auto& item : myMultiSet) {
        std::cout << item << " "; // 输出剩余元素
    }
    std::cout << std::endl;

    // 8. 清空 unordered_multiset
    myMultiSet.clear();
    std::cout << "清空后元素数量: " << myMultiSet.size() << std::endl; // 输出 0

    return 0;
}

4、unordered_multimap

内置函数unordered_mapunordered_multimap
元素访问
operator[]支持。如果键不存在,则插入默认值。不支持。
at支持。如果键不存在,则抛出异常。不支持。
容量操作  empty  size  max_size
修改器
clear支持支持
insert支持。如果键已存在,则不会插入。支持。允许插入重复键。
emplace支持。如果键已存在,则不会插入。支持。允许插入重复键。
emplace_hint支持。如果键已存在,则不会插入。支持。允许插入重复键。
try_emplace (C++17)支持。如果键已存在,则不会插入。不支持。
erase支持。删除指定键的键值对。支持。删除指定键的所有键值对。
swap支持支持
extract (C++17)支持。提取指定键的节点支持。提取指定键的节点
merge (C++17)支持。从另一个容器合并节点支持。从另一个容器合并节点
查找操作
find支持。返回指向第一个匹配键的迭代器。支持。返回指向第一个匹配键的迭代器
count支持。返回匹配键的数量(0 或 1)。支持。返回匹配键的数量(可能大于 1)
contains (C++20)支持。检查容器是否包含指定键。支持。检查容器是否包含指定键

equal_range

支持。返回匹配键的范围(最多一个键值对)支持。返回匹配键的范围(可能有多个键值对)
桶操作   

bucket_count        bucket_size        bucket

哈希操作load_factor    max_load_factor        rehash        reserve
#include <iostream>
#include <unordered_map>

int main() {
    // 1. 创建 unordered_multimap
    std::unordered_multimap<int, std::string> myMultiMap;

    // 2. 插入元素
    myMultiMap.insert({1, "apple"});
    myMultiMap.insert({2, "banana"});
    myMultiMap.insert({2, "berry"}); // 插入重复键
    myMultiMap.insert({3, "cherry"});
    myMultiMap.insert({1, "apricot"}); // 再次插入键 1

    // 3. 输出元素
    std::cout << "unordered_multimap 中的元素: " << std::endl;
    for (const auto& pair : myMultiMap) {
        std::cout << pair.first << ": " << pair.second << std::endl; // 输出所有键值对
    }

    // 4. 查找元素
    auto range = myMultiMap.equal_range(2);
    std::cout << "键 2 对应的值: ";
    for (auto it = range.first; it != range.second; ++it) {
        std::cout << it->second << " "; // 输出所有对应值
    }
    std::cout << std::endl;

    // 5. 计数元素
    std::cout << "键 1 的出现次数: " << myMultiMap.count(1) << std::endl; // 输出 2
    std::cout << "键 2 的出现次数: " << myMultiMap.count(2) << std::endl; // 输出 2
    std::cout << "键 4 的出现次数: " << myMultiMap.count(4) << std::endl; // 输出 0

    // 6. 删除元素
    myMultiMap.erase(2); // 删除所有键为 2 的元素
    std::cout << "删除键 2 后的元素: " << std::endl;
    for (const auto& pair : myMultiMap) {
        std::cout << pair.first << ": " << pair.second << std::endl; // 输出剩余元素
    }

    // 7. 清空 unordered_multimap
    myMultiMap.clear();
    std::cout << "清空后元素数量: " << myMultiMap.size() << std::endl; // 输出 0

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/980208.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于YOLO11深度学习的遥感视角农田检测与分割系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分割、人工智能

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

RabbitMQ面试题及原理

RabbitMQ使用场景&#xff1a; 异步发送&#xff08;验证码、短信、邮件…&#xff09;MYSQL和Redis, ES之间的数据同步分布式事务削峰填谷 1. 消息可靠性&#xff08;不丢失&#xff09; 消息丢失场景&#xff1a; RabbitMQ-如何保证消息不丟失&#xff1f; 开启生产者确…

Python每日一练:学习指南进行汇总

Python&#xff0c;一种“优雅”、“明确”、“简单”的编程语言&#xff0c;凭借其低学习曲线、强大的开源生态系统、卓越的平台可移植性以及面向对象和函数式编程的支持&#xff0c;成为了众多开发者首选。 01 Python 应用领域和就业形势分析 Python&#xff0c;一种“优雅…

商米科技前端工程师(base上海)内推

1.根据原型或高保真设计&#xff0c;开发web、H5、小程序等类型的前端应用&#xff1b; 2.在指导下&#xff0c;高质量完成功能模块的开发&#xff0c;并负责各功能模块接口设计工作&#xff1b; 3.负责产品及相关支撑系统的开发及维护工作&#xff0c;不断的优化升级&#x…

八. Spring Boot2 整合连接 Redis(超详细剖析)

八. Spring Boot2 整合连接 Redis(超详细剖析) 文章目录 八. Spring Boot2 整合连接 Redis(超详细剖析)2. 注意事项和细节3. 最后&#xff1a; 在 springboot 中 , 整合 redis 可以通过 RedisTemplate 完成对 redis 的操作, 包括设置数据/获取数据 比如添加和读取数据 具体…

【漫话机器学习系列】113.逻辑回归(Logistic Regression) VS 线性回归(Linear Regression)

逻辑回归 vs 线性回归&#xff1a;详解对比 在机器学习和统计学中&#xff0c;逻辑回归&#xff08;Logistic Regression&#xff09; 和 线性回归&#xff08;Linear Regression&#xff09; 都是非常常见的模型。尽管它们的数学表达式有一定的相似性&#xff0c;但它们的应用…

构建智能 SQL 查询代理agent,把整个查询过程模块化,既能自动判断使用哪些表,又能自动生成 SQL 语句,最终返回查询结果

示例代码&#xff1a; import os import getpass from dotenv import load_dotenv from pyprojroot import here from typing import List from pprint import pprint from pydantic import BaseModel from langchain_core.tools import tool from langchain_core.runnables i…

fastapi中的patch请求

目录 示例测试使用 curl 访问&#xff1a;使用 requests 访问&#xff1a;预期返回&#xff1a; 浏览器访问 示例 下面是一个使用 app.patch("") 的 FastAPI 示例&#xff0c;该示例实现了一个简单的用户信息更新 API。我们使用 pydantic 定义数据模型&#xff0c;并…

【文献阅读】Collective Decision for Open Set Recognition

基本信息 文献名称&#xff1a;Collective Decision for Open Set Recognition 出版期刊&#xff1a;IEEE TRANSACTIONS ON KNOWLEDGE AND DATA ENGINEERING 发表日期&#xff1a;04 March 2020 作者&#xff1a;Chuanxing Geng and Songcan Chen 摘要 在开集识别&#xff0…

Hadoop之02:MR-图解

1、不是所有的MR都适合combine 1.1、map端统计出了不同班级的每个学生的年龄 如&#xff1a;(class1, 14)表示class1班的一个学生的年龄是14岁。 第一个map任务&#xff1a; class1 14 class1 15 class1 16 class2 10第二个map任务&#xff1a; class1 16 class2 10 class…

代码随想录Day23 | 39.组合总和、40.组合总和II、131.分割回文串

39.组合总和 自己写的代码&#xff1a; class Solution { public:vector<int> path;vector<vector<int>> res;int sum0;void backtracking(vector<int>& candidates,int target,int startIndex){if(sum>target) return;if(sumtarget){res.pus…

【MySQL】索引(页目录、B+树)

文章目录 1. 引入索引2. MySQL与磁盘交互的基本单位3. 索引的理解3.1 页目录3.2 B树 4. 聚簇索引、非聚簇索引5. 索引的操作5.1 索引的创建5.1.1 创建主键索引5.1.2 创建唯一索引5.1.3 普通索引的创建5.1.4 全文索引的创建 5.2 索引的查询5.3 删除索引 1. 引入索引 索引&#…

132. 分割回文串 II

简单分析 输入的参数是字符串s&#xff0c;返回值是最小的切割次数。那这个问题的典型解法应该是动态规划&#xff0c;因为我们需要找最优解&#xff0c;而每一步的选择可能会影响后面的结果&#xff0c;但可以通过子问题的最优解来构建整体最优解。 那么动态规划的状态如何定…

CSS定位详解

1. 相对定位 1.1 如何设置相对定位&#xff1f; 给元素设置 position:relative 即可实现相对定位。 可以使用 left 、 right 、 top 、 bottom 四个属性调整位置。 1.2 相对定位的参考点在哪里&#xff1f; 相对自己原来的位置 1.3 相对定位的特点&#xff1…

NLP11-命名实体识别(NER)概述

目录 一、序列标注任务 常见子任务 二、 命名实体识别&#xff08;NER&#xff09; &#xff08;一&#xff09;简介 &#xff08;二&#xff09;目标 &#xff08;三&#xff09;应用场景 &#xff08;四&#xff09;基本方法 &#xff08;五&#xff09;工具与资源 一…

基于SQL数据库的酒店管理系统

一、数据库设计 1&#xff0e;需求分析 客房的预定&#xff1a;可以通过网络进行预定&#xff0c;预定修改&#xff0c;取消预订。 客房管理&#xff1a;预定管理、客房查询、设置房态、开房、换房、续住、退房等管理。 员工管理: 员工修改信息、人员调配。 账务管理&…

2024年中国城市统计年鉴(PDF+excel)

2024年中国城市统计年鉴&#xff08;PDFexcel&#xff09; 说明&#xff1a;包括地级县级市 格式&#xff1a;PDFEXCEL 《中国城市统计年鉴》是一部全面反映中国城市发展状况的官方统计出版物&#xff0c;包括各级城市的详细统计数据。这部年鉴自1985年开始出版&#xff0c;…

1.C语言初识

C语言初识 C语言初识基础知识hello world数据类型变量、常量变量命名变量分类变量的使用变量的作用域 常量字符字符串转义字符 选择语句循环语句 函数&#xff1b;数组函数数组数组下标 操作符操作符算术操作符移位操作符、位操作符赋值操作符单目操作符关系操作符逻辑操作符条…

LINUX基础 - 网络基础 [一]

前言 在当今的数字化世界中&#xff0c;网络已成为计算机系统和应用的核心组成部分。Linux&#xff0c;作为一个开放源代码的操作系统&#xff0c;在服务器、嵌入式设备、以及开发环境中被广泛使用&#xff0c;而其强大的网络能力使其在网络管理和网络编程领域占据了重要地位。…

苹果廉价机型 iPhone 16e 影像系统深度解析

【人像拍摄差异】 尽管iPhone 16e支持后期焦点调整功能&#xff0c;但用户无法像iPhone 16系列那样通过点击屏幕实时切换拍摄主体。前置摄像头同样缺失人像深度控制功能&#xff0c;不过TrueTone原彩闪光灯系统在前后摄均有保留。 很多人都高估了 iPhone 的安全性&#xff0c;查…