First, I just learn hashing
Second, I wrote the following code to: Whether unordered_set is subset of another unordered_set or not using hash function:
Example:
Let S1=
std::tr1::unordered_set<Sstruct, MyHash> S1{ { 1, 0.9, 0.1 }, { 2, 0.8, 0.2 }, { 3, 0.9, 0.01 }, { 4, 0.7, 0.5 } };
and S2=
std::tr1::unordered_map <int, std::unordered_set< Sstruct, MyHash> > S2;
S2[0].insert({ { 1, 0.933, 0.02 }, { 2, 0.899, 0.3 }, { 3, 0.919, 0.4 } });
S2[1].insert({ { 3, 0.865, 0.1 }, { 4, 0.933, 0.2 }, { 5, 0.919, 0.3 } });
and I want to check if S2[0] is a subset of S1, then if S2[1] is a subset of S1
This the code for that, and it works
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
#include "stdafx.h"
#include <iostream>
#include <boost/tr1/unordered_set.hpp>
#include <boost/tr1/unordered_map.hpp>
struct Sstruct {
int Iv;
float Fv1;
float Fv2;
};
bool operator==(Sstruct a, Sstruct b) { return a.Iv == b.Iv; }
struct MyHash {
size_t operator()(const Sstruct& x) const { return std::hash<int>()(x.Iv); }
};
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, 0.1 }, { 2, 0.8, 0.2 }, { 3, 0.9, 0.01 }, { 4, 0.7, 0.5 } };
std::tr1::unordered_map <int, std::unordered_set<Sstruct, MyHash>> S2;
S2[0].insert({ { 1, 0.933, 0.02 }, { 2, 0.899, 0.3 }, { 3, 0.919, 0.4 } }); // S2 is a subset of S1
S2[1].insert({ { 3, 0.865, 0.1 }, { 4, 0.933, 0.2 }, { 5, 0.919, 0.3 } }); // S2 is not a subset of S1
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 << "S2 is a subset of S1";
else
std::cout << "S2 is not a subset of S1";
std::cout << "\n";
}
std::cin.get();
}
|
Then, I want to edit my code, instead of printing **"S2 is a not subset of S1"**, I want save the result in new `unordered_map` contains:
key: unordered_set of type integer contains `(S1.begin()->Iv, S1.end()->Iv)`
value: three values:
1- summation of `S1` first float value `Fv1`
2- average of `S1` second float value `Fv2`
3- product of (1) and (2)
Note in my program, every time I read different unordered_set `S1`, but here just to Focus on the problem, I initialize one unordered_set `S1`
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
int main()
{
std::tr1::unordered_set<Sstruct, MyHash> S1{ { 1, 0.9, 0.1 }, { 2, 0.8, 0.2 }, { 3, 0.9, 0.01 }, { 4, 0.7, 0.5 } };
std::tr1::unordered_map <int, std::unordered_set<Sstruct, MyHash>> S2;
S2[0].insert( { { 1, 0.933, 0.02 }, { 2, 0.899, 0.3 }, { 3, 0.919, 0.4 }}); // S2 is a subset of S1
S2[1].insert({ { 3, 0.865, 0.1 }, { 4, 0.933, 0.2 }, { 5, 0.919, 0.3 } }); // S2 is not a subset of S1
typedef std::pair<float, float > comp;
typedef std::pair<float, comp> comp2;
std::tr1::unordered_map <std::unordered_set<int>, comp2 > totalval;
comp2 p2;
for (std::tr1::unordered_map <int, std::unordered_set<Sstruct, MyHash>>::const_iterator iter = S2.begin(); iter != S2.end(); ++iter)
{
if ((includes(S1, iter)) == false)
{
float fv1 = 1;
float fv2 = 0;
float fv3 = 1;
std::tr1::unordered_set<Sstruct> ::iterator it = S1.begin();
while (it != S1.end())
{ // if S2 is not a subset of S1
fv1 *= it->Fv1;
fv2 += it->Fv2;
++it;
}
fv2 = fv2 / S1.size();
std::tr1::unordered_set<int> S3(S1.begin()->Iv, S1.end()->Iv);
totalval[S3].first += fv1;
fv3 = fv2 * totalval[S3].first;
totalval[S3].second.first = fv2;
totalval[S3].second.second = fv3;
}
else
std::cout << "S2 is a subset of S1";
}
std::cin.get();
}
|
This is the error I got:
error C2338: The C++ Standard doesn't provide a hash for this type. 1> c:\program files (x86)\microsoft visual studio
12.0\vc\include\type_traits(572) : see reference to class template instantiation 'std::hash<_Kty>' being compiled 1> with 1> [ 1>
_Kty=std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>> 1> ] 1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xhash(196) : see reference to class template instantiation 'std::is_empty<_Hasher>' being compiled 1> with 1> [ 1>
_Hasher=std::hash<std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>>> 1> ] 1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xhash(220) : see reference to class template instantiation 'std::_Hash_oper2<false,_Hasher,_Keyeq>' being compiled 1> with 1> [ 1>
_Hasher=std::hash<std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>>> 1> ,
_Keyeq=std::equal_to<std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>>> 1> ] 1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\unordered_map(23) : see reference to class template instantiation 'std::_Uhash_compare<_Kty,_Hasher,_Keyeq>' being compiled 1> with 1> [ 1>
_Kty=std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>> 1> ,
_Hasher=std::hash<std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>>> 1> ,
_Keyeq=std::equal_to<std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>>> 1> ] 1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xhash(255) : see reference to class template instantiation 'std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>' being compiled 1> with 1> [ 1>
_Kty=std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>> 1> , _Ty=comp2 1> ,
_Hasher=std::hash<std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>>> 1> ,
_Keyeq=std::equal_to<std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>>> 1> , _Alloc=std::allocator<std::pair<const std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>>,comp2>> 1> ] 1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\unordered_map(81) : see reference to class template instantiation 'std::_Hash<std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>' being compiled 1> with 1> [ 1>
_Kty=std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>> 1> , _Ty=comp2 1> ,
_Hasher=std::hash<std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>>> 1> ,
_Keyeq=std::equal_to<std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>>> 1> , _Alloc=std::allocator<std::pair<const std::unordered_set<int,std::hash<int>,std::equal_to<int>,std::allocator<int>>,comp2>> 1> ] 1> c:\users\documents\visual studio 2013\projects\hashtables_set-superset\hashtables_set-superset\hashtables_set-superset.cpp(52) : see reference to class template instantiation 'std::unordered_map<std::unordered_set<int,std::hash<int>,std::equal_to<_Kty>,std::allocator<_Kty>>,comp2,std::hash<std::unordered_set<_Kty,std::hash<int>,std::equal_to<_Kty>,std::allocator<_Kty>>>,std::equal_to<std::unordered_set<_Kty,std::hash<int>,std::equal_to<_Kty>,std::allocator<_Kty>>>,std::allocator<std::pair<const std::unordered_set<_Kty,std::hash<int>,std::equal_to<_Kty>,std::allocator<_Kty>>,_Ty>>>' being compiled 1> with 1> [ 1> _Kty=int 1> , _Ty=comp2 1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========