我知道一个解决方案是使用includes(),但我尝试使用哈希函数来改善运行时间。
我一般不喜欢哈希!!
在我的代码中,我将结构Sstruct
定义为:
struct Sstruct {
int V1;
float Vs;
};
我也有S1
,unordered_set
类Sstruct
有4个整数元素,每个元素都与浮点值相关联。设S1 =
S1 = { { 1, 0.933 },{ 2, 0.899 }, { 3, 0.919 }, { 4, 0.726 } }
我的S2
为unordered_map
,其值unordered_set
为Sstruct
。设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();
}