使用哈希表实现unordered_set ,在哈希表中将密钥哈希到哈希表的索引中,以便始终将插入随机化。 unordered_set上的所有操作平均需要花费恒定时间O(1) ,在最坏的情况下,该时间可能会增加到线性时间O(n) ,这取决于内部使用的哈希函数,但实际上它们执行得很好,并且通常提供恒定时间查找操作。
unordered_set可以包含任何类型的键-预定义或用户定义的数据结构,但是当我们定义类型的键时,用户定义类型,我们需要根据要比较的键来指定比较函数。
集合与无序集合
Set是唯一键的有序序列,而unordered_set是可以以任何顺序存储键(因此无序)的集合。 Set被实现为平衡的树结构,这就是为什么可以维持元素之间的顺序(通过特定的树遍历)的原因。设置操作的时间复杂度为O(log n),而对于unordered_set,则为O(1)。
无序集上的方法:
对于unordered_set,定义了许多函数,其中大多数用户为大小,而容量为空,查找用户以搜索键,插入并擦除以进行修改。
Unordered_set仅允许唯一键,对于重复键,应使用unordered_multiset。
下面给出了在unordered_set中进行声明,查找,插入和迭代的示例:
CPP
// C++ program to demonstrate various function of unordered_set
#include
using namespace std;
int main()
{
// declaring set for storing string data-type
unordered_set stringSet ;
// inserting various string, same string will be stored
// once in set
stringSet.insert("code") ;
stringSet.insert("in") ;
stringSet.insert("c++") ;
stringSet.insert("is") ;
stringSet.insert("fast") ;
string key = "slow" ;
// find returns end iterator if key is not found,
// else it returns iterator to that key
if (stringSet.find(key) == stringSet.end())
cout << key << " not found" << endl << endl ;
else
cout << "Found " << key << endl << endl ;
key = "c++";
if (stringSet.find(key) == stringSet.end())
cout << key << " not found\n" ;
else
cout << "Found " << key << endl ;
// now iterating over whole set and printing its
// content
cout << "\nAll elements : ";
unordered_set :: iterator itr;
for (itr = stringSet.begin(); itr != stringSet.end(); itr++)
cout << (*itr) << endl;
}
CPP
// C++ program to find duplicate from an array using
// unordered_set
#include
using namespace std;
// Print duplicates in arr[0..n-1] using unordered_set
void printDuplicates(int arr[], int n)
{
// declaring unordered sets for checking and storing
// duplicates
unordered_set intSet;
unordered_set duplicate;
// looping through array elements
for (int i = 0; i < n; i++)
{
// if element is not there then insert that
if (intSet.find(arr[i]) == intSet.end())
intSet.insert(arr[i]);
// if element is already there then insert into
// duplicate set
else
duplicate.insert(arr[i]);
}
// printing the result
cout << "Duplicate item are : ";
unordered_set :: iterator itr;
// iterator itr loops from begin() till end()
for (itr = duplicate.begin(); itr != duplicate.end(); itr++)
cout << *itr << " ";
}
// Driver code
int main()
{
int arr[] = {1, 5, 2, 1, 4, 3, 1, 7, 2, 8, 9, 5};
int n = sizeof(arr) / sizeof(int);
printDuplicates(arr, n);
return 0;
}
输出:
slow not found
Found c++
All elements :
is
fast
c++
in
code
查找,插入和擦除平均需要花费固定的时间。如果没有设置键,则find()函数将迭代器返回给end(),否则返回键位置的迭代器。迭代器用作指向键值的指针,因此我们可以使用*运算符它们进行解引用来获取键。
一个基于unordered_set的实际问题–给定一个整数数组(列表),找到其中的所有重复项。
Input : arr[] = {1, 5, 2, 1, 4, 3, 1, 7, 2, 8, 9, 5}
Output : Duplicate item are : 5 2 1
以下是使用unordered_set的C++解决方案。
CPP
// C++ program to find duplicate from an array using
// unordered_set
#include
using namespace std;
// Print duplicates in arr[0..n-1] using unordered_set
void printDuplicates(int arr[], int n)
{
// declaring unordered sets for checking and storing
// duplicates
unordered_set intSet;
unordered_set duplicate;
// looping through array elements
for (int i = 0; i < n; i++)
{
// if element is not there then insert that
if (intSet.find(arr[i]) == intSet.end())
intSet.insert(arr[i]);
// if element is already there then insert into
// duplicate set
else
duplicate.insert(arr[i]);
}
// printing the result
cout << "Duplicate item are : ";
unordered_set :: iterator itr;
// iterator itr loops from begin() till end()
for (itr = duplicate.begin(); itr != duplicate.end(); itr++)
cout << *itr << " ";
}
// Driver code
int main()
{
int arr[] = {1, 5, 2, 1, 4, 3, 1, 7, 2, 8, 9, 5};
int n = sizeof(arr) / sizeof(int);
printDuplicates(arr, n);
return 0;
}
输出 :
Duplicate item are : 5 1 2
unordered_set的方法:
- insert()–在unordered_set容器中插入一个新的{element}。
- begin()–返回指向unordered_set容器中第一个元素的迭代器。
- end()–返回指向过去的end-element的迭代器。
- count()–计算unordered_set容器中特定元素的出现次数。
- find()–在容器中搜索元素。
- clear()–从unordered_set中删除所有元素并将其清空。
- cbegin()–返回指向unordered_set容器中第一个元素的const_iterator。
- cend()–返回const_iterator,该指针指向unordered_set容器或其中一个存储桶中的past-the-end元素。
- bucket_size()–返回unordered_set容器中特定存储桶中存在的元素总数。
- 擦除()–删除从开始(包括)到结束(不包括)的一系列元素中的单个元素。
- size()–返回unordered_set容器中的元素数。
- swap()–交换两个unordered_set容器的值。
- emplace()–在unordered_set容器中插入一个元素。
- max_size()–返回unordered_set容器可以容纳的最大元素数。
- empty()–检查unordered_set容器是否为空。
- equal_range –返回包含等于给定值的所有元素的范围。
- 运算符= –将unordered_set复制(或移动)到另一个unordered_set,并且unordered_set :: 运算符=是相应的运算符函数。
- hash_function()–此哈希函数是一元函数,仅接受单个参数,并根据该参数返回size_t类型的唯一值。
- reserve()–用于请求unordered_set的容量更改。
- bucket()–返回特定元素的存储桶编号。
- bucket_count()–返回存在于unordered_set容器中的存储桶总数。
- load_factor()–返回unordered_set容器中的当前负载系数。
- rehash()–将unordered_set容器中的存储桶数设置为给定大小或更大。
- max_load_factor()–返回(或设置)无序集合容器的当前最大负载系数。
- emplace_hint()–仅在要插入的值是唯一且具有给定提示的情况下,才在unordered_set中插入新元素。
- ==运算符–’==’是C++ STL中的运算符,它在两个无序集合之间执行相等比较操作,并且unordered_set :: 运算符==是相同的对应运算符函数。
- key_eq()–根据比较结果返回布尔值。它返回unordered_set使用的键等效项比较谓词。
- 运算符!= –!=是C++ STL中的关系运算符,用于比较unordered_set容器之间的相等性和不相等性。
- max_bucket_count()–查找unordered_set可以具有的最大存储桶数。