unordered_set是以key为元素无序的关联容器,搜索、移除和插入操作是平均常数的时间复杂度。unordered_set在内部没有按任何顺序排列,而是放在桶当中的,放进哪个桶是通过计算key的hash值来决定的。
template<
class Key,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator<Key>
> class unordered_set;
本文章的代码库:
https://gitee.com/gamestorm577/CppStd
成员函数
构造、析构和赋值
构造函数
可以构造一个空的unordered_set,也可以用迭代器、另一个unordered_set或者元素列表来构造一个unordered_set。构造的时候还可以指定最小桶数、hash函数、比较函数或者分配器。代码示例:
std::vector<int> tmp{1, 2, 3, 4};
std::unordered_set<int> s1;
std::unordered_set<int> s2(tmp.begin(), tmp.end());
std::unordered_set<int> s3(s2);
std::unordered_set<int> s4{1, 2, 3};
std::cout << "s1 size = " << s1.size() << std::endl;
std::cout << "s2 size = " << s2.size() << std::endl;
std::cout << "s3 size = " << s3.size() << std::endl;
std::cout << "s4 size = " << s4.size() << std::endl;
输出结果:
s1 size = 0
s2 size = 4
s3 size = 4
s4 size = 3
对于自定义的类型,需要定义hash函数以及比较函数。代码示例:
struct MyStruct
{
int Num1;
double Num2;
};
struct MyHash
{
std::size_t operator()(const MyStruct& val) const
{
return std::hash<int>()(val.Num1) + std::hash<double>()(val.Num2);
}
};
struct MyEqual
{
bool operator()(const MyStruct& lhs, const MyStruct& rhs) const
{
return true;
}
};
std::unordered_set<MyStruct, MyHash, MyEqual> s;
析构函数
销毁unordered_set时,会调用各元素的析构函数。代码示例:
struct MyStruct
{
MyStruct(int i)
: Num(i)
{
}
~MyStruct()
{
std::cout << "destruct, Num = " << Num << std::endl;
}
int Num = 0;
};
struct MyHash
{
std::size_t operator()(const MyStruct& val) const
{
return std::hash<int>()(val.Num);
}
};
struct MyEqual
{
bool operator()(const MyStruct& lhs, const MyStruct& rhs) const
{
return lhs.Num == rhs.Num;
}
};
std::unordered_set<MyStruct, MyHash, MyEqual> s{1, 2, 3};
std::cout << "end" << std::endl;
输出结果:
destruct, Num = 3
destruct, Num = 2
destruct, Num = 1
end
destruct, Num = 3
destruct, Num = 2
destruct, Num = 1
赋值函数
可以用另一个unordered_set或者元素列表给unordered_set赋值。代码示例:
std::unordered_set<int> tmp{1, 2, 3};
std::unordered_set<int> s1;
std::unordered_set<int> s2;
s1 = tmp;
s2 = {1, 2, 3, 4};
std::cout << "s1 size = " << s1.size() << std::endl;
std::cout << "s2 size = " << s2.size() << std::endl;
输出结果:
s1 size = 3
s2 size = 4
迭代器
接口begin、cbegin指向unordered_set起始的迭代器,end、cend指向末尾的迭代器。无论什么迭代器都不能修改元素的值。代码示例:
std::unordered_set<int> s{1, 2, 3};
for (auto iter = s.begin(); iter != s.end(); ++iter)
{
std::cout << "num = " << *iter << std::endl;
}
输出结果:
num = 3
num = 2
num = 1
容量
empty
检查unordered_set是否为空。代码示例:
std::unordered_set<int> s1{1, 2, 3};
std::unordered_set<int> s2;
std::cout << std::boolalpha;
std::cout << "s1 empty: " << s1