C++容器——集合(unordered_set)
·
1. 简介
unordered_set是一种关联式容器,包含的key值唯一,不会进行排序;增加、修改和查询具有线性的时间复杂度,其存储结构为哈希表;
头文件和定义
#include <unordered_set>
template<
class Key,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator<Key>
> class unordered_set;
2. 初始化
unordered_set的初始化方法如下所示
/*
* @brief unordered_set
* @g++ -g unordered_set_main.cc -o d -std=c++11
* @author
* @date 2023/03/27
*/
#include <iostream>
#include <unordered_set>
#include <string>
template<typename T>
void showInfo(T& t)
{
for(const auto& au : t)
{
std::cout<<au<<" ";
}
std::cout<<std::endl;
}
int main(int argc, char* argv[])
{
std::unordered_set<std::string> un_s1;
un_s1.emplace("c++");
un_s1.emplace("c");
un_s1.insert("java");
un_s1.insert("Rust");
showInfo(un_s1);
//直接初始化
std::unordered_set<std::string> un_s2{"student", "teacher", "boy", "girl", "class1", "class2", "score"};
showInfo(un_s2);
//拷贝初始化
std::unordered_set<std::string> un_s3 = un_s1;
showInfo(un_s3);
return 0;
}
输出
Rust java c++ c
class2 class1 teacher score girl boy student
Rust java c++ c
3. 使用
3.1 元素访问
| 方法 | 说明 |
|---|---|
| iterator | 集合元素的遍历 |
unordered_set不支持下标访问
示例
int main(int argc, char* argv[])
{
std::unordered_set<std::string> un_s1{"student", "teacher", "boy", "girl", "class1", "class2", "score"};
auto iter = un_s1.begin();
while(iter != un_s1.end())
{
std::cout<<*iter<<" ";
iter++;
}
std::cout<<std::endl;
return 0;
}
输出
class2 class1 teacher score girl boy student
3.2 集合大小
| 方法 | 说明 |
|---|---|
| empty | 集合判空 |
| size | 集合大小 |
| max_size | 最大容量 |
| clear | 清空unordered_set的大小 |
| swap | 交换两个unordered_set的内容 |
int main(int argc, char* argv[])
{
//empty size max_size clear swap
std::unordered_set<std::string> un_s1{"student", "teacher", "boy", "girl", "class1", "class2", "score"};
showInfo(un_s1);
std::cout<<"size() is: "<<un_s1.size()<<"\n";
std::cout<<"max_size() is: "<<un_s1.max_size()<<"\n\n";
std::unordered_set<std::string> un_s2;
un_s1.swap(un_s2);
std::cout<<"[un_s1]"<<std::endl;
showInfo(un_s1);
std::cout<<"[un_s2]"<<std::endl;
showInfo(un_s2);
std::cout<<std::endl;
un_s2.clear();
if(un_s2.empty())
{
std::cout<<"empty\n";
}
else{
std::cout<<"not empty\n";
}
}
输出
class2 class1 teacher score girl boy student
size() is: 7
max_size() is: 384307168202282325
[un_s1]
[un_s2]
class2 class1 teacher score girl boy student
empty
3.3 元素的修改
| 方法 | 说明 |
|---|---|
| = | 直接赋值 |
| get_allocator | 返回内存分配器 |
| insert | 插入元素 |
| emplace | 插入元素 |
| emplace_hint | 插入元素,需要添加位置 |
| erase | 删除元素 |
| erase_if(C++20) | 条件删除,通常和lambda一起使用 |
| extract(C++17) | 元素的删除,可以返回该值 |
| merge(C++17) | unordered_set的合并 |
示例
int main(int argc, char* argv[])
{
//operator= get_allocator insert emplace emplace_hint erase extract merge
std::unordered_set<std::string> un_s1{"c++"};
un_s1.insert("c");
un_s1.emplace("Rust");
un_s1.emplace_hint(un_s1.begin(), "golang");
showInfo(un_s1);
std::cout<<std::endl;
un_s1.erase(un_s1.begin());
std::cout<<"[erase]"<<std::endl;
showInfo(un_s1);
std::cout<<std::endl;
//extract
auto re = un_s1.extract(un_s1.begin());
showInfo(un_s1);
std::cout<<std::endl;
//merge
std::unordered_set<std::string> un_s2{"student", "teacher", "boy", "girl"};
un_s1.merge(un_s2);
showInfo(un_s1);
showInfo(un_s2); //输出空
return 0;
}
输出
Rust c golang c++
[erase]
c golang c++
golang c++
c++ golang student boy girl teacher
3.5 元素的操作
桶是内部的存储结构
| 方法 | 说明 |
|---|---|
| count | 计算unordered_set中元素出现的次数 |
| find | 查找元素 |
| equal_range | 返回的是一个范围 [lower_bound, upper_bound] |
| bucket_count | 返回桶的数量 |
| max_bucket_count | 返回桶可以达到的最大数量 |
| bucket_size(n) | 返回第n个桶中元素的数量 |
| bucket | 返回元素在第几个桶中 |
| load_factor | 返回桶的平均元素数 |
| max_load_factor | 返回最大负载系数 |
| rehash(n) | 设定桶的数目为n |
| reserve(n) | 设定桶的数目最少为n |
| hash_function | 返回一个唯一的大小为size_t的值 |
| key_eq | 返回unordered_set使用的键等效项比较谓词 |
示例1
int main(int argc, char* argv[])
{
std::unordered_set<std::string> un_s1{"c", "Rust", "golang"};
showInfo(un_s1);
auto iter = un_s1.find("c");
std::cout<<*iter<<std::endl;
std::cout<<"count() test "<<un_s1.count("golang")<<std::endl;
//equal_range
auto equal_iter = un_s1.equal_range("Rust");
std::cout<<*equal_iter.first<<std::endl;
std::cout<<*equal_iter.second<<std::endl;
//bucket_count max_bucket_count bucket_size bucket
//桶
std::cout<<"un_s1 bucket_count() value is: "<<un_s1.bucket_count()<<std::endl; //返回当前桶的数量,从0到n-1
std::cout<<"un_s1 max_bucket_count() value is: "<<un_s1.max_bucket_count()<<"\n\n"; //返回最大桶的数量
std::cout<<"un_s1 "<<un_s1.bucket_size(1)<<"\n\n"; //返回桶1中元素的个数
for(int32_t i = 0; i<un_s1.bucket_count(); i++)
{
std::cout<<"size of "<<i<<" bucket is: "<<un_s1.bucket_size(i)<<std::endl;
}
std::cout<<std::endl;
std::cout<<"the location of Rust is: "<<un_s1.bucket("Rust")<<std::endl; //返回"Rust"在第几个桶中
return 0;
}
输出
golang Rust c
c
count() test 1
Rust
c
un_s1 bucket_count() value is: 5
un_s1 max_bucket_count() value is: 384307168202282325
un_s1 0
size of 0 bucket is: 0
size of 1 bucket is: 0
size of 2 bucket is: 1
size of 3 bucket is: 1
size of 4 bucket is: 1
the location of Rust is: 3
示例2
int main(int argc, char* argv[])
{
std::unordered_set<std::string> un_s1{"c++", "c", "Rust", "golang", "linux", "matlab"};
showInfo(un_s1);
std::cout<<"bucket_count is: "<<un_s1.bucket_count()<<std::endl;
std::cout<<"un_s1.size is: "<<un_s1.size()<<std::endl;
//load_factor,返回桶的平均元素数 size()/bucket_count()
std::cout<<"load_factor value is: "<<un_s1.load_factor()<<std::endl;
//max_load_factor,返回最大负载系数
std::cout<<"max_load_factor value is: "<<un_s1.max_load_factor()<<std::endl;
//rehash,设定桶的数目
un_s1.rehash(10);
std::cout<<"bucket_count after rehash is: "<<un_s1.bucket_count()<<std::endl;
//reserve,设置桶的数目(最少包含20个)
un_s1.reserve(20);
std::cout<<"bucket_count after reserve is: "<<un_s1.bucket_count()<<std::endl;
//hash_function,返回一个唯一的大小为size_t的值
auto au_hash = un_s1.hash_function();
std::cout<<au_hash("c")<<std::endl;
//key_eq,返回unordered_set使用的键等效项比较谓词
auto au_key = un_s1.key_eq()("c","c");
if(au_key)
{
std::cout<<"equal"<<std::endl;
}
else{
std::cout<<"not equal"<<std::endl;
}
return 0;
}
输出
matlab Rust linux golang c c++
bucket_count is: 7
un_s1.size is: 6
load_factor value is: 0.857143
max_load_factor value is: 1
bucket_count after rehash is: 11
bucket_count after reserve is: 23
10959529184379665549
equal
3.6 迭代器
迭代器最好结合STL中的算法一起使用;迭代器的返回值最好用auto接收;
迭代器的类型包括:iterator和const_iterator
| 方法 | 说明 |
|---|---|
| begin | 返回unordered_set的头元素(迭代器),其值可修改 |
| end | 返回unordered_set的尾元素(迭代器),其值可修改 |
| cbegin | 返回set的头元素(迭代器),其值不可修改,const属性 |
| cend | 返回set的尾元素(迭代器),其值不可修改,const属性 |
迭代器的辅助函数
辅助函数的使用需要包含头文件
#include <iterator>
| 方法 | 说明 |
|---|---|
| advance | 移动迭代器的位置 |
| distance | 计算两个迭代器的距离 |
| begin | 返回容器第一个元素的迭代器 |
| end | 返回容器最后一个元素的迭代器 |
| prev | 迭代器向前移动一个元素 |
| next | 迭代器向后移动一个元素 |
示例
int main(int argc, char* argv[])
{
std::unordered_set<std::string> un_s1{"c++", "c", "Rust", "golang", "linux", "matlab"};
showInfo(un_s1);
std::cout<<std::endl;
auto au = un_s1.begin();
while (au != un_s1.end())
{
std::cout<<*au<<" ";
au++;
}
std::cout<<std::endl;
auto au_begin = un_s1.begin();
std::advance(au_begin,2);
std::cout<<*au_begin<<std::endl;
au_begin = un_s1.begin();
auto au_end = un_s1.end();
std::cout<<std::distance(au_begin,au_end)<<std::endl;
return 0;
}
输出
matlab Rust linux golang c c++
matlab Rust linux golang c c++
linux
6
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)