C ++使用哈希函数检查unordered_set是否是另一个unordered_set的子集

时间:2014-06-11 20:15:21

标签: c++ boost hash

我知道一个解决方案是使用includes(),但我尝试使用哈希函数来改善运行时间。

我一般不喜欢哈希!!

在我的代码中,我将结构Sstruct定义为:

 struct Sstruct {
            int V1;
            float Vs;
        };

我也有S1unordered_setSstruct有4个整数元素,每个元素都与浮点值相关联。设S1 =

S1 = { { 1, 0.933 },{ 2, 0.899 }, { 3, 0.919 }, { 4, 0.726 } }

我的S2unordered_map,其值unordered_setSstruct。设S2 =

S2 ={ 
     { { 1, 0.933 },{ 2, 0.899 }, { 3, 0.919 }, { 4, 0.726 } },
     { { 2, 0.906 },{ 3, 0.994 }, { 4, 0.726 } },
     { { 3, 0.865 },{ 4, 0.933 }, { 5, 0.919 } }
    }

我想检查S2是否是S1的子集

这意味着:

我检查S2中的第一个unordered_set:{{1,0.933},{2,0.899},{3,0.919},{4,0.726}}是S1的子集: {{1,0.933},{2,0.899},{3,0.919},{4,0.726}}

注意:我只关心unordered_set中的整数

然后,我检查S2中的第二个unordered_set是否是来自S1的子集 然后,我检查S2中的第三个unordered_set是否是来自S1的子集

当我将unordered_set声明为整数时,程序正常工作:

std::tr1::unordered_set<int> 

但它给了我错误:error C2338: The C++ Standard doesn't provide a hash for this type,当我将unordered_set声明为 Sstruct 时:

    std::tr1::unordered_set<Sstruct>  

更新

我解决了错误,感谢@praetorian告诉我必须使用std :: hash的特化作为我的结构,我花了很多时间阅读它,我并不是说我完全理解了整个哈希的想法,但我在这个过程中。

还要感谢@ pavel-minaev

和: How to specialize std::hash<Key>::operator() for user-defined type in unordered containers?

+ How to determine if a list is subset of another list?

更新后的代码:

#include "stdafx.h"
#include <iostream> 
#include <boost/tr1/unordered_set.hpp>
#include <boost/tr1/unordered_map.hpp>

struct Sstruct {
    int V1;
    float Vf;
};


    bool operator==(Sstruct a, Sstruct b) { return a.V1 == b.V1; }

    struct MyHash {
        size_t operator()(const Sstruct& x) const { return std::hash<int>()(x.V1); }
    };

    std::unordered_set<Sstruct, MyHash> s;

    std::tr1::unordered_map <int, std::unordered_set<Sstruct, MyHash>> S2;



    bool includes(const std::tr1::unordered_set<Sstruct, MyHash>& S1, const std::tr1::unordered_map <int, std::unordered_set<Sstruct, MyHash>>::const_iterator& iter)
{


        for ( std::tr1::unordered_set<Sstruct, MyHash>::const_iterator iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2)

            if (S1.find(*iter2) == S1.end())
            {
                    return false;
                }

            return true;



}

int main()
{

    std::tr1::unordered_set<Sstruct, MyHash> S1{ { 1, 0.9 }, { 2, 0.8 }, { 3, 0.9 }, { 4, 0.7 } };

    S2[0].insert( { { 1, 0.933 }, { 2, 0.899 }, { 3, 0.919 }, { 4, 0.726 } });
    S2[1].insert({ { 2, 0.906 }, { 3, 0.994 }, { 4, 0.726 } });
    S2[2].insert({ { 3, 0.865 }, { 4, 0.933 }, { 5, 0.919 } });


    for (std::tr1::unordered_map <int, std::unordered_set<Sstruct, MyHash>>::const_iterator iter = S2.begin(); iter != S2.end(); ++iter)
    {
        if ((includes(S1, iter)) == true)
            std::cout << "S1 is a superset of S2";
        else
            std::cout << "S1 not a superset of S2";
        std::cout << "\n";
    }

    std::cin.get();
}

0 个答案:

没有答案