You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何声明存储vector<unordered_set<int>>的set/unordered_set并解决相关问题

关于std::vector<std::unordered_set<int>>去重的容器适配问题

我需要声明一个变量存储std::vector<std::unordered_set<int>>类型的元素以实现自动去重,考虑用std::set或std::unordered_set,但遇到两个问题:

  1. 尝试用std::unordered_set声明时:
std::unordered_set<std::vector<std::unordered_set<int>>, \
boost::hash<std::vector<std::unordered_set<int>>>> Variable1;

出现错误:boost::hash_value - none of the 3 overloads could convert all the argument types,想知道有没有boost或非boost的合适哈希函数?
2. 用std::set声明时:

std::set<std::vector<std::unordered_set<int>>> Variable2;

需要为std::vector<std::unordered_set<int>>实现<比较运算符,有没有预定义的实现方式?


一、为std::vector<std::unordered_set<int>>提供哈希函数(适配std::unordered_set)

Boost方式

Boost的hash默认不支持哈希std::unordered_set,你需要手动为std::unordered_set<int>扩展哈希实现,让boost::hash能递归处理vector:

#include <boost/functional/hash.hpp>
#include <unordered_set>
#include <vector>

namespace boost {
    template<typename T>
    std::size_t hash_value(const std::unordered_set<T>& s) {
        std::size_t seed = 0;
        for (const auto& elem : s) {
            boost::hash_combine(seed, elem);
        }
        return seed;
    }
}

// 现在可正常声明
std::unordered_set<std::vector<std::unordered_set<int>>, boost::hash<std::vector<std::unordered_set<int>>>> Variable1;

Boost的hash本身支持vector,只要元素类型能被哈希,就能自动处理整个容器的哈希计算。

非Boost方式(标准库自定义哈希)

自己实现哈希结构体,分别处理unordered_set<int>和嵌套的vector:

#include <unordered_set>
#include <vector>
#include <functional>

struct HashUnorderedSet {
    std::size_t operator()(const std::unordered_set<int>& s) const {
        std::size_t seed = 0;
        for (int num : s) {
            std::hash<int> hasher;
            seed ^= hasher(num) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
        }
        return seed;
    }
};

struct HashVectorOfUnorderedSets {
    std::size_t operator()(const std::vector<std::unordered_set<int>>& vec) const {
        std::size_t seed = 0;
        HashUnorderedSet set_hasher;
        for (const auto& s : vec) {
            seed ^= set_hasher(s) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
        }
        return seed;
    }
};

// 声明方式
std::unordered_set<std::vector<std::unordered_set<int>>, HashVectorOfUnorderedSets> Variable1;

这里用标准库std::hash<int>,通过0x9e3779b9(黄金分割数,减少哈希碰撞)组合每个元素的哈希值,生成整个容器的最终哈希。


二、为std::vector<std::unordered_set<int>>实现<比较运算符(适配std::set)

标准库已经为std::vector提供了默认的<运算符(按顺序逐个比较元素),但std::unordered_set是无序容器,标准库不提供默认的<比较。你只需要给unordered_set<int>实现一个全序比较,vector的默认比较就能生效:

#include <unordered_set>
#include <vector>
#include <algorithm>

bool operator<(const std::unordered_set<int>& lhs, const std::unordered_set<int>& rhs) {
    if (lhs.size() != rhs.size()) {
        return lhs.size() < rhs.size();
    }
    // 转成有序vector再比较,保证全序关系
    std::vector<int> lhs_vec(lhs.begin(), lhs.end());
    std::vector<int> rhs_vec(rhs.begin(), rhs.end());
    std::sort(lhs_vec.begin(), lhs_vec.end());
    std::sort(rhs_vec.begin(), rhs_vec.end());
    return lhs_vec < rhs_vec;
}

// 现在可直接声明set
std::set<std::vector<std::unordered_set<int>>> Variable2;

逻辑很简单:先比较集合大小,大小不同直接按大小判断;大小相同就转成有序vector,用vector的默认比较得到稳定的全序关系,满足std::set的排序要求。

内容的提问来源于stack exchange,提问作者Tryer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:23:13