关于C++中的unordered_map和unordered_set不能直接以pair作为键名的问题

关于C++中的unordered_map和unordered_set不能直接以pair作为键名的问题

在 C++ STL 中,不同于有序的 std::mapstd::set 是基于红黑树实现的,std::unordered_mapstd::unordered_set 是基于哈希实现的,在不要求容器内的键有序,仅要求查找效率较高时,哈希实现的后者时更为合适的,哈希表的运用也经常出现在各种算法题中。

但是,我们知道,既然是基于哈希实现的,那么就需要指定哈希函数。对于内置的数据类型如 intfloatchar 等,STL 库已经帮助我们内置了常用的哈希函数。因此通常,我们在使用这些数据类型组成的 unordered_map 和 unordered_set 可以不再指定哈希函数,直接用默认的。这在 unordered_map 的类模板定义中也可看到:

template < class Key,            //容器中存储元素的类型
           class Hash = hash<Key>,    //确定元素存储位置所用的哈希函数
           class Pred = equal_to<Key>,   //判断各个元素是否相等所用的函数
           class Alloc = allocator<Key>   //指定分配器对象的类型
           > class unordered_set;

在这些参数重,只有第一个参数是没有默认值的。也就是说,在我们创建 intchar 等内置类型的 unordered_set 时只需要传入存储在容器中的类型即可。

但是,对于没有默认的哈希函数的类型,如自定义的 class 类型,pair 类型等,我们就必须自己指定一个哈希函数。这也是为什么直接构建 pair 类型的 unordered_set 如 unordered_set<pair<int, int>> uset 会出现问题(不会在声明时报错,而是在 insert 等操作时)。

对于这种情况,我们只需要将上面的第二个参数:确定元素存储位置所用的哈希函数,也在声明时传入就行了。关于哈希函数的选择,不同的情景会有所不同。这里笔者给出一个最简单的针对 pair 类型的哈希函数。

struct SimplePairHash {
    std::size_t operator()(const std::pair<int, int>& p) const {
        return p.first ^ p.second;
    }
};

在声明时直接将其传入即可:

std::unordered_set<std::pair<int, int>, SimplePairHash> S;
S.insert(std::make_pair(0, 1));

Ref :

https://stackoverflow.com/questions/21288345/unordered-set-of-pairs-compilation-error

https://blog.csdn.net/pineappleKID/article/details/108341064

在C语言,unordered_set的函数包括: - begin():返回一个迭代器,指向unordered_set的第一个元素。 - end():返回一个迭代器,指向unordered_set的末尾(最后一个元素的下一个位置)。 - insert(const K& key):将一个元素插入到unordered_set,并返回一个pair对象,其的iterator指向插入的元素,bool值表示是否插入成功。 - find(const K& key):查找unordered_set是否存在指定的元素,如果找到,则返回一个指向该元素的迭代器;如果找不到,则返回end()。 - erase(const K& key):从unordered_set删除指定的元素,如果删除成功,则返回true;如果删除失败(即元素不存在),则返回false。 需要注意的是,在C语言,unordered_set的函数并不是直接在C标准库提供的,而是通过自定义的unordered_set类实现的。所以,使用unordered_set函数之前,需要先引入相应的头文件,并使用对应的命名空间。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [初识C++之unordered_map与unordered_set](https://blog.csdn.net/Masquerena114514/article/details/129938734)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [c++ unordered_set 函数参考](https://blog.csdn.net/weixin_46183779/article/details/119979647)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值