I know that one solution is by using includes(), but I'm trying to improve the run time using hash function.
I'm not good with hashing in general!!
In my code, I have struct namely Sstruct
is defined as:
struct Sstruct {
int V1;
float Vs;
};
I also have S1
as unordered_set
of type Sstruct
has 4 integer elements, and each element associated with float values. Let S1=
S1 = { { 1, 0.933 },{ 2, 0.899 }, { 3, 0.919 }, { 4, 0.726 } }
and I have S2
as unordered_map
where its values is unordered_set
of Sstruct
. Let 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 } }
}
and I want to check if S2 is subset from S1
this means:
I check if the first unordered_set in S2
: { { 1, 0.933 },{ 2, 0.899 }, { 3, 0.919 }, { 4, 0.726 } } is subset from S1
: { { 1, 0.933 },{ 2, 0.899 }, { 3, 0.919 }, { 4, 0.726 } }
note: I only care about the integer number in the unordered_set
then, I check if the second unordered_set in S2
is subset from S1
then, I check if the third unordered_set in S2
is subset from S1
The program work okay when I declare my unordered_set as integer like:
std::tr1::unordered_set<int>
but it gives me error: error C2338: The C++ Standard doesn't provide a hash for this type
, when I declare my unordered_set as Sstruct like:
std::tr1::unordered_set<Sstruct>
Update:
I solved the errors thanks to @praetorian for telling me that I have to use a specialization of std::hash for my struct, I spent many hours reading about it, I'm not saying I become full understand the whole hashing idea but I'm in the process.
thanks also to @pavel-minaev
and: 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?
This the code after updating:
#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();
}