【C++关联式容器】unordered_set

news2024/11/28 16:27:06

目录

unordered_set

1. 关联式容器额外的类型别名

2. 哈希桶

3. 无序容器对关键字类型的要求

4. Member functions

4.1 constructor、destructor、operator=

4.1.1 constructor

4.1.2 destructor

4.1.3 operator= 

4.2 Capacity

​4.2.1 empty

4.2.2 size

4.2.3 max_size

4.3 Iterators

4.4 Element lookup

4.4.1 find

4.4.2 count

4.4.3 equal_range

4.5 Modifiers

4.5.1 emplace

4.5.2 emplace_hint

4.5.3 insert

4.5.4 erase

4.5.5 clear

4.5.6 swap

4.6 Buckets

4.6.1 bucket_count

4.6.2 max_bucket_count

4.6.3 bucket_size

4.6.4 bucket

4.7 Hash policy

4.7.1 load_factor

4.7.2 max_load_factor

4.7.3 rehash

4.7.4 reserve

4.8 Observers

4.8.1 hash_function

4.8.2 key_eq

4.8.3 get_allocator

5. Non-member function overloads

5.1 operators

5.2 swap

6. unordered_set对象的遍历方法

6.1 迭代器

6.2 范围for


unordered_set

template < class Key,                        // unordered_set::key_type/value_type
           class Hash = hash<Key>,           // unordered_set::hasher
           class Pred = equal_to<Key>,       // unordered_set::key_equal
           class Alloc = allocator<Key>      // unordered_set::allocator_type
           > class unordered_set;

unordered_set是一种容器,它存储的元素没有特定的顺序,允许根据元素的值快速获取单个元素。

在unordered_set中,一个元素的值与它的键同时存在,从而唯一地标识它。键是不可变的,因此unordered_set中的元素一旦进入容器就不能被修改——但它们可以被插入和删除。

在内部,unordered_set中的元素没有按任何特定的顺序排序,而是根据它们的哈希值组织成,以允许直接通过值快速访问各个元素(平均时间复杂度是常数)。

在通过键访问单个元素时,unordered_set容器比set容器更快,尽管在通过元素子集进行范围迭代时通常效率较低。

容器中的迭代器至少是前向迭代器。

unordered_set定义在头文件unordered_set和命名空间std中。

1. 关联式容器额外的类型别名

key_type此容器类型的关键字类型
mapped_type每个关键字关联的类型;只适用于map
value_type对于set,与key_type相同
对于map,为pair<const key_type, mapped_type>

对于set类型,key_type和value_type是一样的:set中保存的值就是关键字。在一个map中,元素是键值对。即,每个元素是一个pair对象,包含一个关键字和一个关联的值。由于我们不能改变一个元素的关键字,因此这些pair的关键字部分是const的:

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

与序列式容器一样,我们使用作用域运算符来提取一个类型的成员——例如,map<string, int>::key_type。

只有map类型(unordered_map、unordered_multimap、multimap和map)才定义了mapped_type。

2. 哈希桶

无序容器在存储上组织为一组桶,每个桶保存零个或多个元素。无序容器使用一个哈希函数将元素映射到桶。为了访问一个元素,容器首先计算元素的哈希值,它指出应该搜索哪个桶。容器将具有一个特定哈希值的所有元素都保存在相同的桶中。如果容器允许重复关键字,所有具有相同关键字的元素也都会在同一个桶中。因此,无序容器的性能依赖于哈希函数的质量和桶的数量和大小。

对于相同的参数,哈希函数必须总是产生相同的结果。理想情况下,哈希函数还能将每个特定的值映射到唯一的桶。但是,将不同关键字的元素映射到相同的桶也是允许的。当一个桶保存多个元素时,需要顺序搜索这些元素来查找我们想要的那个。计算一个元素的哈希值和在桶中搜索通常都是很快的操作。但是,如果一个桶中保存了很多元素,那么查找一个特定元素就需要大量比较操作。

3. 无序容器对关键字类型的要求

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

但是,我们不能直接定义关键字类型为自定义类类型的无序容器。与容器不同,不能直接使用哈希模板,而必须提供我们自己的hash模板版本。

4. Member functions

4.1 constructor、destructor、operator=

4.1.1 constructor

// empty (1)
explicit unordered_set(size_type n ,
					   const hasher& hf = hasher(),
					   const key_equal& eql = key_equal(),
					   const allocator_type& alloc = allocator_type());
explicit unordered_set(const allocator_type& alloc);
// range (2)
template <class InputIterator>
unordered_set(InputIterator first, InputIterator last,
			  size_type n,
			  const hasher& hf = hasher(),
			  const key_equal& eql = key_equal(),
			  const allocator_type& alloc = allocator_type());
// copy (3)
unordered_set(const unordered_set& ust);
unordered_set(const unordered_set& ust, const allocator_type& alloc);
// move (4)
unordered_set(unordered_set&& ust);
unordered_set(unordered_set&& ust, const allocator_type& alloc);
// initializer list (5)
unordered_set(initializer_list<value_type> il,
			  size_type n,
			  const hasher& hf = hasher(),
			  const key_equal& eql = key_equal(),
		  	  const allocator_type& alloc = allocator_type());

// n表示初始桶的最小数量,不是容器中元素的数量

4.1.2 destructor

~unordered_set();

4.1.3 operator= 

// copy (1)
unordered_set& operator=(const unordered_set& ust);
// move (2)
unordered_set& operator=(unordered_set&& ust);
// initializer list (3)
unordered_set& operator=(intitializer_list<value_type> il);

4.2 Capacity

​4.2.1 empty

bool empty() const noexcept;
// 检测unordered_set是否为空,是返回true,否则返回false

4.2.2 size

size_type size() const noexcept;
// 返回unordered_set中元素的个数

4.2.3 max_size

size_type max_size() const noexcept;
// 返回unordered_set能够容纳的最大元素个数

4.3 Iterators

// begin
// container iterator (1)
iterator begin() noexcept;
const_iterator begin() const noexcept;
// bucket iterator (2)
local_iterator begin(size_type n);
const_local_iterator begin(size_type n) const;

// end
// container iterator (1)
iterator end() noexcept;
const_iterator end() const noexcept;
// bucket iterator (2)
local_iterator end(size_type n);
const_local_iterator end(size_type n) const;

// cbegin
// container iterator (1)
const_iterator cbegin() const noexcept;
// bucket iterator (2)
const_local_iterator cbegin(size_type n) const;

// cend
// container iterator (1)
const_iterator cend() const noexcept;
// bucket iterator (2)
const_local_iterator cend(size_type n) const;
函数功能

begin

&

end

(1)版本begin返回一个迭代器,指向unordered_set中第一个元素

(2)版本begin返回一个迭代器,指向unordered_set中桶n的第一个元素

(1)版本end返回一个迭代器,指向unordered_set中最后一个元素的下一个位置

(2)版本end返回一个迭代器,指向unordered_set中桶n的最后一个元素的下一个位置

cbegin

&

cend

(1)版本cbegin返回一个const迭代器,指向unordered_set中第一个元素

(2)版本cbegin返回一个const迭代器,指向unordered_set中桶n的第一个元素

(1)版本cend返回一个const迭代器,指向unordered_set中最后一个元素的下一个位置

(2)版本cend返回一个const迭代器,指向unordered_set中桶n的最后一个元素的下一个位置

#include <unordered_set>
#include <iostream>
using namespace std;

int main()
{
    unordered_set<string> ust{ "iterator","begin","end" };

    cout << "ust contains:" << endl;
    unordered_set<string>::iterator it = ust.begin();
    while (it != ust.end())
    {
        cout << *it << endl;
        ++it;
    }
    // ust contains :
    // iterator
    // begin
    // end

    cout << "ust's buckets contain:" << endl;
    for (int i = 0; i < ust.bucket_count(); ++i)
    {
        cout << "bucket #" << i << " contains:";
        unordered_set<string, string>::local_iterator lit = ust.begin(i);
        while (lit != ust.end(i))
        {
            cout << " " << *lit;
            ++lit;
        }
        cout << endl;
    }
    // ust's buckets contain:
    // bucket #0 contains:
    // bucket #1 contains:
    // bucket #2 contains: end
    // bucket #3 contains:
    // bucket #4 contains:
    // bucket #5 contains:
    // bucket #6 contains: begin
    // bucket #7 contains: iterator

    return 0;
}

4.4 Element lookup

4.4.1 find

iterator find(const key_type& k);
const_iterator find(const key_type& k) const;
// 返回一个迭代器,指向第一个关键字为k的元素,若k不在容器中,则返回end迭代器

4.4.2 count

size_type count(const key_type& k) const;
// 返回关键字等于k的元素的数量
// 对于不允许重复关键字的容器,返回值永远是0或1
#include <unordered_set>
#include <iostream>
using namespace std;

int main()
{
	int arr[5] = { 1,2,6,7,8 };
	unordered_set<int> ust(arr, arr + 5);

	auto it = ust.find(2);
	if (it != ust.end())
	{
		cout << "2在unordered_set中" << endl;
	}
	else
	{
		cout << "2不在unordered_set中" << endl;
	}
	// 2在unordered_set中

	it = ust.find(3);
	if (it != ust.end())
	{
		cout << "3在unordered_set中" << endl;
	}
	else
	{
		cout << "3不在unordered_set中" << endl;
	}
	// 3不在unordered_set中

	if (ust.count(7))
	{
		cout << "7在unordered_set中" << endl;
	}
	else
	{
		cout << "7不在unordered_set中" << endl;
	}
	// 7在unordered_set中

	if (ust.count(5))
	{
		cout << "5在unordered_set中" << endl;
	}
	else
	{
		cout << "5不在unordered_set中" << endl;
	}
	// 5不在unordered_set中

	return 0;
}

4.4.3 equal_range

pair<iterator, iterator> equal_range(const key_type& k);
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
// 返回一个迭代器pair,表示关键字等于k的元素的范围(左闭右开的区间)
// 若k不存在,pair的两个成员均为end迭代器
// 对于不允许重复关键字的容器,返回的范围最多只包含一个元素

4.5 Modifiers

4.5.1 emplace

template <class... Args> pair<iterator, bool> emplace(Args&&... args);
// 对应insert,区别是:
// 当调用insert时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中
// 当调用emplace时,则是将参数传递给元素类型的构造函数,然后使用这些参数在容器管理的内存空间中直接构造元素

4.5.2 emplace_hint

template <class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
// 对应insert的(3)和(4),区别是:
// 当调用insert时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中
// 当调用emplace时,则是将参数传递给元素类型的构造函数,然后使用这些参数在容器管理的内存空间中直接构造元素

4.5.3 insert

// (1) 成功返回pair<插入位置, true>,失败返回pair<插入位置, false>
pair<iterator, bool> insert(const value_type& val);
// (2)
pair<iterator, bool> insert(value_type&& val);
// (3)
iterator insert(const_iterator hint, const value_type& val);
// (4)
iterator insert(const_iterator hint, value_type&& val);
// (5)
template <class InputIterator> void insert(InputIterator first, InputIterator last);
// (6)
void insert(initializer_list<value_type> il);

// 插入

4.5.4 erase

// by position(1)
iterator erase(const_iterator position);
// by key(2)
size_type erase(const key_type& k);
// range(3)
iterator erase(const_iterator first, const_iterator last);

// 删除

4.5.5 clear

void clear() noexcept;
// 清空

4.5.6 swap

void swap(unordered_set& ust);
// 交换

4.6 Buckets

4.6.1 bucket_count

size_type bucket_count() const noexcept;
// 返回unordered_set中桶的个数

4.6.2 max_bucket_count

size_type max_bucket_count() const noexcept;
// 返回unordered_set能够容纳的最大桶个数

4.6.3 bucket_size

size_type bucket_size(size_type n) const;
// 返回桶n中元素的个数

4.6.4 bucket

size_type bucket(const key_type& k) const;
// 返回关键字为k的元素所在的桶号

4.7 Hash policy

4.7.1 load_factor

float load_factor() const noexcept;
// 返回负载因子(每个桶平均元素的数量,元素的数量/桶的数量)

4.7.2 max_load_factor

// get(1)
float max_load_factor() const noexcept;
// set(2)
void max_load_factor(float z);

// 获取或设置最大负载因子

4.7.3 rehash

void rehash(size_type n);
// 设置桶的数量

4.7.4 reserve

void reserve(size_type n);
// 将桶数设置为最适合包含至少n个元素的桶数

4.8 Observers

4.8.1 hash_function

hasher hash_function() const;
// 返回哈希函数

4.8.2 key_eq

key_equal key_eq() const;
// 返回关键字等价比较谓词

4.8.3 get_allocator

allocator_type get_allocator() const noexcept;
// 返回空间配置器

5. Non-member function overloads

5.1 operators

// equality (1)
template <class Key, class Hash, class Pred, class Alloc>
bool operator==(const unordered_set<Key, Hash, Pred, Alloc>& lhs, const unordered_set<Key, Hash, Pred, Alloc>& rhs);
// inequality (2)
template <class Key, class Hash, class Pred, class Alloc>
bool operator!=(const unordered_set<Key, Hash, Pred, Alloc>& lhs, const unordered_set<Key, Hash, Pred, Alloc>& rhs);

5.2 swap

template <class Key, class Hash, class Pred, class Alloc>
void swap(unordered_set<Key, Hash, Pred, Alloc>& lhs, unordered_set<Key, Hash, Pred, Alloc>& rhs);

6. unordered_set对象的遍历方法

6.1 迭代器

#include <unordered_set>
#include <iostream>
using namespace std;

int main()
{
	int arr[5] = { 1,2,6,7,8 };
	unordered_set<int> ust(arr, arr + 5);

	unordered_set<int>::iterator it = ust.begin();
	while (it != ust.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	// 1 2 6 7 8

	return 0;
}

6.2 范围for

#include <unordered_set>
#include <iostream>
using namespace std;

int main()
{
	int arr[5] = { 1,2,6,7,8 };
	unordered_set<int> ust(arr, arr + 5);

	for (auto& e : ust)
	{
		cout << e << " ";
	}
	cout << endl;
	// 1 2 6 7 8

	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【每日一题】牛客网——链表的回文结构

✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有限&#xff0c;欢迎各位大佬指点&#xff0c;相互学习…

FT2232调试记录(3)

FT2232调试记录&#xff08;1&#xff09;: FT2232调试记录&#xff08;2&#xff09;: FT2232调试记录&#xff08;3&#xff09;: FT2232 SPI读写函数: 参照SPI提供的文档&#xff1a; 工程&#xff1a; SPI 写函数&#xff1a; FT_STATUS write_byte(FT_HANDLE handle…

【2024年毕设系列】如何使用Anaconda和Pycharm

【2024年毕设系列】如何使用Anaconda和Pycharm 视频教程地址&#xff1a;【2024毕设系列】Anaconda和Pycharm如何使用_哔哩哔哩 Hi&#xff0c;各位好久不见&#xff0c;这里是肆十二&#xff0c;首先在这里给大伙拜年了。 诸位过完年之后估计又要开始为了大作业和毕业设计头疼…

Java+SpringBoot实习管理系统探秘

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

响应式编程四Spring WebFlux高阶实战,2W字干货!!

响应式编程四Spring WebFlux高阶实战 WebFlux作为核心响应式服务器基础响应式Web内核响应式Web和MVC框架基于WebFlux的纯函数式Web基于WebClient的非阻塞跨服务通讯Spring Web Flux 和Spring Web MVC对比 WebFlux的应用基于微服务的系统 大文件上传Spring WebFlux数据库访问集成…

“从根到叶:深入理解堆数据结构“

​​​​​​​ 一.堆的概念及实现 1.1堆的概念 在数据结构中&#xff0c;堆是一种特殊的树形数据结构。堆可以分为最大堆和最小堆两种类型。 最大堆&#xff1a;对于堆中的任意节点&#xff0c;其父节点的值都不小于它的值。换句话说&#xff0c;最大堆中的根节点是堆中的最…

【Java 数据结构】泛型进阶

泛型 1 什么是泛型2 引出泛型2.1 语法 3 泛型类的使用3.1 语法3.2 示例3.3 类型推导(Type Inference) 泛型是如何编译的擦除机制裸类型4 泛型的上界4.1 语法4.2 示例4.3 复杂示例 5 泛型方法5.1 定义语法5.2 示例5.3 使用示例-可以类型推导5.4 使用示例-不使用类型推导 6 通配符…

【电路笔记】-串联电感

串联电感 文章目录 串联电感1、概述2、电感串联示例13、互耦串联电感器4、电感串联示例25、电感串联示例36、总结当电感器以菊花链方式连接在一起并共享公共电流时,它们可以串联连接在一起。 1、概述 这些电感器的互连产生了更复杂的网络,其总电感是各个电感器的组合。 然而…

深度学习从入门到不想放弃-7

上一章的内容 深度学习从入门到不想放弃-6 (qq.com) 今天讲的也算基础(这个系列后来我一寻思,全是基础 ),但是可能要着重说下,今天讲前向计算和反向传播,在哪儿它都永远是核心,不管面对什么模型 前向计算: 有的叫也叫正向传播,正向计算的,有的直接把前向的方法梯度下…

九、优化强度(Optimizing Intensity)

7.Optimizing Intensity 七、优化强度 Researchers have known for decades that there is a relationship between the optimal intensity of attention and the complexity of the task you want to perform. 数十年来&#xff0c;研究者已经知道你想要完成的任务的复杂性与最…

【AI视野·今日CV 计算机视觉论文速览 第299期】Mon, 29 Jan 2024

AI视野今日CS.CV 计算机视觉论文速览 Mon, 29 Jan 2024 Totally 55 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers Annotated Hands for Generative Models Authors Yue Yang, Atith N Gandhi, Greg TurkGAN 和扩散模型等生成模型已经展示了…

【C/C++】2024春晚刘谦春晚魔术步骤模拟+暴力破解

在这个特别的除夕夜&#xff0c;我们不仅享受了与家人的温馨团聚&#xff0c;还被电视机前的春节联欢晚会深深吸引。特别是&#xff0c;魔术师刘谦的精彩表演&#xff0c;为我们带来了一场视觉和心灵的盛宴。在我的博客“【C/C】2024春晚刘谦春晚魔术步骤模拟暴力破解”中&…

OpenCV基础:用Python生成一幅随机的噪声图像

使用Python&#xff1a;生成一幅随机数值的灰度图像&#xff0c;图像大小为1616像素。借助OpenCV库。输出数值&#xff0c;并显示图像。 # -*- coding: utf-8 -*- """ Created on Wed Feb 14 21:49:09 2024author: 李立宗公众号&#xff1a;计算机视觉之光知识…

证明之毕达哥拉斯定理

毕达哥拉斯定理 毕达哥拉斯的著名定理所讲的是&#xff0c;假设一直角三角形的三边长为a、b和c&#xff0c;其中c是斜边长&#xff08;直角所对的边&#xff09;&#xff0c;则 a 2 b 2 c 2 a^2b^2c^2 a2b2c2。这个定理有若干种证明&#xff0c;其中有一种特别简短&#xf…

【黑马程序员】C++封装、对象特性、友元

文章目录 类和对象封装封装的意义struct和class的区别成员属性设置为私有封装练习设计立方体类点和圆的关系 对象的初始化和清理构造函数和析构函数构造函数析构函数 构造函数的分类及调用拷贝构造函数的调用时机构造函数调用规则深拷贝与浅拷贝浅拷贝深拷贝 初始化列表类对象作…

matplotlib雷达图制作具体步骤

此次我们制作的是关于护肤品下的畅销品类雷达图&#xff0c;数据如下&#xff1a; 数据预览&#xff1a; 一、代码展示 import pandas as pd import numpy as np import matplotlib.pyplot as plt plt.rcParams[font.sans-serif][SimHei] adress"D:/pandas练习文件/雷达…

JAVA设计模式之解释器模式详解

解释器模式 1 解释器模式介绍 解释器模式使用频率不算高&#xff0c;通常用来描述如何构建一个简单“语言”的语法解释器。它只在一些非常特定的领域被用到&#xff0c;比如编译器、规则引擎、正则表达式、SQL 解析等。不过&#xff0c;了解它的实现原理同样很重要&#xff0…

零基础学编程怎么入手,中文编程工具构件箱之星空构件用法教程,系统化的编程视频教程上线

零基础学编程怎么入手&#xff0c;中文编程工具构件箱之星空构件用法教程&#xff0c;系统化的编程视频教程上线 一、前言 今天给大家分享的中文编程开发语言工具资料如下&#xff1a; 编程入门视频教程链接 http://​ https://edu.csdn.net/course/detail/39036 ​ 编程…

Java17之使用Lambda表达式对对象集合中指定的字段进行排序

Java17之使用Lambda表达式对对象集合中指定的字段进行排序 文章目录 Java17之使用Lambda表达式对对象集合中指定的字段进行排序1. 集合对象排序1. Java实体类2. 正序排序3.倒序排序 1. 集合对象排序 Java8起可用 List 的 sort 方法进行排序&#xff0c;形参为函数式接口Compara…

C++ //练习 6.12 改写6.2.1节中练习6.10(第188页)的程序,使用引用而非指针交换两个整数的值。你觉得哪种方法更易于使用呢?为什么?

C Primer&#xff08;第5版&#xff09; 练习 6.12 练习 6.12 改写6.2.1节中练习6.10&#xff08;第188页&#xff09;的程序&#xff0c;使用引用而非指针交换两个整数的值。你觉得哪种方法更易于使用呢&#xff1f;为什么&#xff1f; 环境&#xff1a;Linux Ubuntu&#x…