473,387 Members | 1,664 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

STL hash_map hash

I have a requirement where I have to use two unsigned ints as a key in a STL
hash map.
A couple of ways to do this is
1. create a struct with two unsigned ints and use that as key (write my own
HashFcn and EqualKey template args) or,
2. convert the two unsigned ints to char*s, concatenate them and use that as
Key.

For method 1, the difficulty I am having is in writing the HashFcn. HashFcn
requires the following method
size_t operator()(const T& x)
I cannot create a unique hash for two unsigned ints for the hash_map that is
a size_t.

To try method 2, I thought of first trying with just one unsigned int
converted to a char* and use that as Key.
The result of it was that the hash key generated happened to be the same for
two different unsigned ints
causing one of them to be dropped.

Please suggest solution that would work to create an STL hash_map with 2
unsigned ints as Key.

Here is the code that does that:

#include <iostream>
#include <ext/hash_map>

using namespace std;
using namespace __gnu_cxx;

struct eqstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) == 0;
}
};

int main()
{
hash_map<const char*, unsigned int, hash<const char*>, eqstr> hash_obj;

hash<const char*> hashfun;

char key[32];

sprintf(key, "%u", (((unsigned int)~0) / 2) + 250000000);
hash_obj[key] = (((unsigned int)~0) / 2) + 250000000;
cout << "Hash for " << key << " = " << hashfun(key) << endl;

sprintf(key, "%u", (((unsigned int)~0) / 2) + 300000000);
hash_obj[key] = (((unsigned int)~0) / 2) + 300000000;
cout << "Hash for " << key << " = " << hashfun(key) << endl;

for(hash_map<const char*, unsigned int, hash<const char*>,
eqstr>::const_iterator i = hash_obj.begin();
i != hash_obj.end(); i++)
{
cout << "hash_obj[" << (*i).first << "] = " << (*i).second << endl;
}
}

/* g++ /usr/include/c++/3.3 -o post post.cc -lstdc++ */

The output was
Hash for 2397483647 = 123096165
Hash for 2447483647 = 123096165
hash_obj[2447483647] = 2447483647

Jul 22 '05 #1
3 4127
Murali wrote:
I have a requirement where I have to use two unsigned ints as a key in a STL
hash map.


There is no "hash map" in the STL.

Jul 22 '05 #2
On Sun, 08 Feb 2004 20:10:03 GMT in comp.lang.c++, "Murali"
<mu****@email.com> was alleged to have written:
I cannot create a unique hash for two unsigned ints for the hash_map that is
a size_t.
You fundamentally cannot create a unique hash of size N bits for all
keys of size M > N bits. That is part of what hashing is all about.
You want a hash function such that the mapping of the keys to the hash
values is uncorrelated with and looks random relative to the key values
that you are likely to encounter.

Doesn't hash_map come with a suitable default hashing function? It's
not part of standard C++ yet so I wouldn't know. ;-)

Lacking a default I would probably try using CRC32 over all the bytes of
the key. Google "CRC32 source code"
The result of it was that the hash key generated happened to be the same for
two different unsigned ints causing one of them to be dropped.


Neither should be dropped if EqualKey says they are not equal, even if
the hash is the same.

Don't waste time converting your keys to strings, if you can help it.

Jul 22 '05 #3

"Murali" <mu****@email.com> wrote in message
news:vI******************@newssvr28.news.prodigy.c om...
I have a requirement where I have to use two unsigned ints as a key in a STL hash map.
A couple of ways to do this is
1. create a struct with two unsigned ints and use that as key (write my own HashFcn and EqualKey template args) or,
2. convert the two unsigned ints to char*s, concatenate them and use that as Key.

For method 1, the difficulty I am having is in writing the HashFcn. HashFcn requires the following method
size_t operator()(const T& x)
I cannot create a unique hash for two unsigned ints for the hash_map that is a size_t.
You don't have to create a unique hash. Hash tables work perfectly well
without unique hash values. Just exclusive-or the two integers together,
that's a prefectly good hash function.

To try method 2, I thought of first trying with just one unsigned int
converted to a char* and use that as Key.
The result of it was that the hash key generated happened to be the same for two different unsigned ints
causing one of them to be dropped.
No that does not happen when you have duplicate hash values. Duplicate hash
values are called 'collisions'. The skill in writing a hashing algorithm is
in dealing with the collisions, but they do not stop a hash table working.

Please suggest solution that would work to create an STL hash_map with 2
unsigned ints as Key.

Here is the code that does that:

#include <iostream>
#include <ext/hash_map>

using namespace std;
using namespace __gnu_cxx;

struct eqstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) == 0;
}
};

int main()
{
hash_map<const char*, unsigned int, hash<const char*>, eqstr> hash_obj;
hash<const char*> hashfun;

char key[32];

sprintf(key, "%u", (((unsigned int)~0) / 2) + 250000000);
hash_obj[key] = (((unsigned int)~0) / 2) + 250000000;
cout << "Hash for " << key << " = " << hashfun(key) << endl;

sprintf(key, "%u", (((unsigned int)~0) / 2) + 300000000);
Here's your problem, you are using key as your key, but you are overwriting
it when you add the second value.

Try this

char key1[32];
char key2[32];

sprintf(key1, "%u", (((unsigned int)~0) / 2) + 250000000);
hash_obj[key1] = (((unsigned int)~0) / 2) + 250000000;
cout << "Hash for " << key << " = " << hashfun(key1) << endl;
sprintf(key2, "%u", (((unsigned int)~0) / 2) + 300000000);
hash_obj[key2] = (((unsigned int)~0) / 2) + 300000000;
cout << "Hash for " << key << " = " << hashfun(key2) << endl;>

or just go back to using two unsigned int, instead of strings.

Incidentally how dod you think that the STL generates unique hash values for
indefinte length strings and fits them into a size_t? Impossible, no?
hash_obj[key] = (((unsigned int)~0) / 2) + 300000000;
cout << "Hash for " << key << " = " << hashfun(key) << endl;>
for(hash_map<const char*, unsigned int, hash<const char*>,
eqstr>::const_iterator i = hash_obj.begin();
i != hash_obj.end(); i++)
{
cout << "hash_obj[" << (*i).first << "] = " << (*i).second << endl; }
}

/* g++ /usr/include/c++/3.3 -o post post.cc -lstdc++ */

The output was
Hash for 2397483647 = 123096165
Hash for 2447483647 = 123096165
hash_obj[2447483647] = 2447483647


john

Jul 22 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Mark | last post by:
Hi, I'm trying to use hash_map (gcc 3.2.2) with a std::string as the key. It will compile if I use <map> but I get a bunch of template compile errors when I change it to hash_map. Any...
4
by: Christian Meier | last post by:
Hello, Yes, I know that hash maps aren't in the standard. But I couldn't find any better newsgroup for this post. (or is there an SGI library newsgroup?) I am currently testing the hash_map...
5
by: peter_k | last post by:
Hi I've defined hash_map in my code using this: ------------------------------------------- #include <string> #include <hash_map.h> & namespace __gnu_cxx {
3
by: kony | last post by:
Hi there, I would much appreciate your help with the following problem. Below is the code that uses a hash_map. I want to release all the memory occupied by the hash_map for other use. Apparently...
4
by: lokki | last post by:
Hello, can anybody tell me what's wrong with following example code? char *k, *v; k = new char; strcpy(k, "a2"); v = new char;
11
by: aaragon | last post by:
Hello everyone, I have a VERY BIG set of double values that I want to map to intervals so I thought a clever way to do this was using a hash table. Let's say that I want to map all double values...
1
by: Axel Gallus | last post by:
Hello, i have a question concerning STL non-standard hash_maps under Visual Studio 2005: Microsoft STL requires a "hash_compare" object for hash_maps: template <class Key, class Type, class...
4
by: James Kanze | last post by:
On Jul 16, 10:53 pm, Mirco Wahab <wa...@chemie.uni-halle.dewrote: It depends. You might like to have a look at my "Hashing.hh" header (in the code at kanze.james.neuf.fr/code-en.html---the...
2
by: marek.vondrak | last post by:
Hi, I am wondering if there are any functional differences between SGI's hash_map and tr1's unordered_map. Can these two containers be interchanged? What would it take to switch from hash_map to...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.