C++标准模板库中的无序集

C++标准模板库中的无序集

unordered_set 是一种无序关联容器,在哈希表中使用哈希函数将键散列到哈希表的索引中,因此插入始终是随机的。所有 unordered_set 上的操作在平均情况下都需要常数时间 O(1) ,在最坏情况下可能需要线性时间 O(n) ,这取决于内部使用的哈希函数,但实际上它们的表现非常好,通常提供一个常数时间的查找操作。

unordered_set可以包含任何类型的键-预定义或用户定义数据结构,但所有键必须是唯一的。它在< unordered_set >头文件中定义为 std::unordered_set 类。

语法:

std::unordered_set<data_type> name;

在std::unordered_set中,定义了许多函数,其中最常用的函数是:

  • size()和empty()用于容量。
  • find()用于搜索关键字。
  • insert()和erase()用于修改。

示例:

// C++程序演示了unordered_set的各种功能
#include <bits/stdc++.h>
using namespace std;
int main()
{
// 声明用于存储字符串数据类型的set
    unordered_set<string> stringSet;
// 将各种字符串插入,重复的字符串只会存储一次
    stringSet.insert("code");
    stringSet.insert("in");
    stringSet.insert("c++");
    stringSet.insert("is");
    stringSet.insert("fast");
    string key = "slow";
// 如果未找到关键字,find()则返回end迭代器;否则,返回到关键字的迭代器
    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;
    cout << "\nAll elements : ";
    unordered_set<string>::iterator itr;
    for (itr = stringSet.begin(); itr != stringSet.end();
            itr++)
        cout << (*itr) << endl;
}

输出

slow not found

Found c++

All elements : is
fast
c++
in
code

find()、insert()和erase()函数平均需要一个恒定的时间。如果在集合中没有关键字,find()函数会返回end()迭代器,否则返回到关键字的迭代器。迭代器作为指向关键字值的指针,因此我们可以通过使用*运算符来解除引用并获取关键字。

我们还可以看到输出的顺序混乱,因为没有特定的顺序来存储unordered_set中的数据。

注意: unordered_set只允许唯一的关键字,而对于重复的关键字应该使用unordered_multiset。

C++STL中的set vs unordered_set

Set 无序集合
Set是一组有序的唯一键序列。 无序集合是一种可以按任意顺序存储键的集合,因此是无序的。
Set是作为平衡树结构实现的,可以通过特定的树遍历方式来维护元素之间的顺序。 无序集合实现为哈希表,因为我们不必担心任何顺序。
Set操作的时间复杂度为O(log n)。 基本Set操作的时间复杂度是O(1)。

在无序集合上的实际问题

给定一个整数数组(列表),找出其中所有的重复项(假设重复项是一个由随机人猜测的相同的数字,在实验中)。

输入:

arr[] = {1, 5, 2, 1, 4, 3, 1, 7, 2, 8, 9, 5}

输出:

重复项为:5 2 1 

例子:

//使用unordered_set从数组中找到重复
//C++程序
#include <bits/stdc++.h>
using namespace std;
 
//使用unordered_set在arr[0…n-1]中打印重复项
void printDuplicates(int arr[], int n)
{
    //声明unordered sets用于检查和存储
    //重复
    unordered_set<int> intSet;
    unordered_set<int> duplicate;
 
    //循环遍历数组元素
    for (int i = 0; i < n; i++) {
        //如果元素不存在则插入该元素
        if (intSet.find(arr[i]) == intSet.end())
            intSet.insert(arr[i]);
 
        //如果元素已经存在,则插入到重复集
        else
            duplicate.insert(arr[i]);
    }
 
    //打印结果
    cout << "重复项为:";
    unordered_set<int>::iterator itr;
 
    //Iterator itr从begin()到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;
}

输出

重复项为:5 2 1 

时间复杂度:O(n log n)
辅助空间:O(n)

std::unordered_set成员方法

以下表格包含std::unordered_set类的所有成员函数:

函数名称 函数描述
insert() 在无序集合容器中插入一个新的 {element}。
begin() 返回指向无序集合容器中第一个元素的迭代器。
end() 返回指向“过去-结束”的元素的迭代器。
count() 统计无序集合容器中特定元素的出现次数。
find() 在容器中查找一个元素。
clear() 删除无序集合中的所有元素并清空容器。
cbegin() 返回指向无序集合容器中第一个元素的const_iterator。
cend() 返回指向无序集合容器或其Buckets中“过去-结束”的元素的const_iterator。
bucket_size() 返回无序集合容器中特定Bucket中存在的元素总数。
erase() 删除单个元素或从开始(包括)到结束(不包括)范围内的一系列元素。
size() 返回无序集合容器中元素的数量。
swap() 交换两个无序集合容器的值。
emplace() 在无序集合容器中插入一个元素。
max_size() 返回无序集合容器可以容纳的最大元素数量。
empty() 检查无序集合容器是否为空。
equal_range 返回包括所有等于给定值的元素的范围。
operator= 将一个无序集合复制(或移动)到另一个无序集合中,unordered_set::operator=是相应的操作函数。
hash_function() 这个哈希函数是一个一元函数,只接受一个参数,并根据它返回一个唯一的size_t类型的值。
reserve() 用于请求无序集合的容量变化。
bucket() 返回特定元素的Bucket编号。
bucket_count() 返回无序集合容器中存在的Bucket总数。
load_factor() 返回无序集合容器中的当前负载因子。
rehash() 将无序集合的容器中的Bucket数设置为给定大小或更大。
max_load_factor() 返回(或设置)无序集合容器的当前最大负载因子。
emplace_hint() 如果要插入的值是唯一的,则仅使用给定提示将新元素插入无序集合中。
operator ’是C++ STL中的一个运算符,用于在两个无序集合之间执行相等比较操作,unordered_set::operator是相应的操作函数。
key_eq() 根据比较返回一个布尔值。返回无序集合使用的键等价比较谓词。
operator!= != 是 C++ STL 中的一个关系运算符,用于比较无序集合容器之间的相等和不相等。
max_bucket_count() 查找 unordered_set 可能具有的最大桶数。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

C++ 教程