In the program below I’ve a typedef map. What I want to do is to implement a hash table. I’m trying to use unordered_map since I heard that is the efficient as it takes O(1) time. I use my typedef map everywhere in my main program (another program that I’m working on) so I don’t want to change that. I want to implement hash table in one of the functions and I’m trying to figure out how to insert the contents of my map into the hash table and search for the key later. I’ve inserted a comment in two places where I’m having trouble. Please help.
#include <iostream>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <unordered_map>
using namespace std;
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;
}
I appreciate any help or comments.
After reading Jason’s comments I understand why i cannot use a std::set as a key in unordered_map so I tried to use std::string as a key but the find function won’t work. Could you please help me.
Mymap c1;
for( m_it it(sample.begin()) ; it!=sample.end(); ++it) {
v_t v1;
std::string key;
key.insert(key.begin(),it->first.begin(),it->first.end());
copy(it->second.begin(), it->second.end(),std::back_inserter(v1));
c1.insert(Mymap::value_type(std::make_pair(key,v1)));
}
string s = "72";
if((c1.find(s) != c1.end()) == true)
cout << "Success" << endl;
return 0;
The basic element you’re missing to make this work is to define a hashing function for your
std::setthat you’re using as the key. The STL already defines equality and lexicographical ordering for astd::set, so you can use it as the key-value in astd::mapas-is without any problems. It does not define a hash function though, so that is something you’re going to have to-do by overloading std::hash. This is fairly straight-forward, and can be done by defining the following function:The above functor object would return an integral type of
size_t, and would take astd::setas the argument. You’ll have to define it inside ofnamespace stdso thatstd::unordered_mapwill recognize it. An “easy” algorithm could be simply summing the elements since you have a set of typeint. There are more complex algorithms out there that would reduce the number of collisions such a simple algorithm would create at the expense of hashing time. Once you have this defined though, you shouldn’t have any problems inserting yourstd::setkey-values into anunordered_map, as well as creating new key-values and finding them in the hash table.You can see an example of your source-code working at: http://ideone.com/DZ5jm
EDIT: Jason’s code placed here for reference: