Основной элемент, который вам не хватает для этой работы, - это определение функции хеширования для вашего std::set
, который вы используете в качестве ключа. STL уже определяет равенство и лексикографический порядок для std::set
, поэтому вы можете без проблем использовать его в качестве значения ключа в std::map
как есть. Однако он не определяет хеш-функцию, так что это то, что вам нужно сделать, перегружая std :: hash. Это довольно просто и может быть сделано путем определения следующей функции:
namespace std
{
template<>
struct hash<std::set<int> > : public std::unary_function<std::set<int>, size_t>
{
size_t operator()(const std::set<int>& my_set) const
{
//insert hash algorithm that returns integral type
}
};
}
Приведенный выше объект функтора возвращает целочисленный тип size_t
и принимает в качестве аргумента std::set
. Вам нужно определить его внутри namespace std
, чтобы std::unordered_map
распознал его. «Легким» алгоритмом может быть просто суммирование элементов, поскольку у вас есть набор типа int
. Существуют более сложные алгоритмы, которые уменьшают количество коллизий, которые такой простой алгоритм может создать за счет времени хеширования. Однако после того, как вы это определили, у вас не должно возникнуть проблем с вставкой значений ключей std::set
в unordered_map
, а также с созданием новых значений ключей и их нахождением в хеш-таблице.
Вы можете увидеть пример вашего исходного кода, работающего по адресу: http://ideone.com/DZ5jm
РЕДАКТИРОВАТЬ: Джейсон код размещены здесь для справки:
#include <iostream>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <unordered_map>
using namespace std;
namespace std
{
template<>
struct hash<set<int> > : public unary_function<set<int>, size_t>
{
size_t operator()(const std::set<int>& my_set) const
{
set<int>::iterator iter = my_set.begin();
int total = 0;
for (; iter != my_set.end(); iter++)
{
total += *iter;
}
return total;
}
};
}
typedef vector<int> v_t;
typedef set<int> s_t;
typedef map<s_t, v_t> m_t;
typedef m_t::iterator m_it;
typedef std::unordered_map<s_t, v_t> Mymap;
int main(){
m_t sample;
for (int i = 0; i < 100; i = i+2) {
v_t v;
for(int k = 100 ; k<=105 ; ++k)
v.push_back(k);
s_t k;
k.insert(i);
sample.insert(sample.end(), make_pair(k, v));
}
//---------Debug--------------------
for( m_it it(sample.begin()) ; it!=sample.end(); ++it) {
cout << "Key: ";
copy(it->first.begin(), it->first.end(), ostream_iterator<int>(cout, " "));
cout << " => Value: ";
copy (it->second.begin(),it->second.end(),ostream_iterator<double>(cout," "));
cout << endl;
}
//---------------------------------
Mymap c1;
for( m_it it(sample.begin()) ; it!=sample.end(); ++it) {
c1.insert(Mymap::value_type(it->first,it->second)); // how to do this ?
}
s_t s;
s.insert(72);
if(c1.find(s)!=c1.end()) // does this work ?
cout << "Success" << endl;
return 0;
}