views:

699

answers:

7

Is there such a structure in c++ standard library? I don't have access to anything else so unordered_map in tr1 cant be used (and boost etc).

What I have is a large number of custom class elements 100000+ which I need to store, and access them very fast O(1) on everage. I can't use arrays/vectors as the elements will be stored randomly and I don't know the position of the element.

Is my only alternative to implements an own hashmap implementation with only the c++ standard library available?

+3  A: 

The problem is that the O(1) lookup is not standard. I am unsure about what boost has, but some STL implementations (like sgi) have hash_map. That's what you need.

Here is the documentation.

Just try out:

#include <hash_map>

Keep in mind if this works, it is not portable... but maybe for now that's ok, and later you can find workarounds.

Tom
Correct me if I'm wrong, but I think I heard the next C++ standard is going to include hash_map. Anyone know this for a fact?
Tom
Boost says: "With this in mind, the C++ Standard Library Technical Report introduced the unordered associative containers, which are implemented using hash tables, and they have now been added to the Working Draft of the C++ Standard."
John Kugelman
Thanks, John! I'm glad I wasn't imagining hearing that somewhere.
Tom
I think that the hash map in the next C++ standard will be named unordered_map.
ChrisW
Well tr1 included the unordered_map container which uses hashing so it should be in the c++0x standard. Visual Studio 2008 already has an implementation under <unordered_map> it seems (although in the tr1 namespace rather than std)
Fire Lancer
Can down voters please comment on why this was a bad response?
Tom
I didn't downvote but your answer sounds confusing at the start: "The problem is that the O(1) lookup is not standard. " < sounds like there is some hash map in the C++ standard - this is just true for some STL implementations, not for C++ standard library implementations (not sure what the questioner means with "default stl" - i recommend avoiding the term "stl" anyway). But might aswell be a different reason for the downvote. i wouldn't know :p
Johannes Schaub - litb
@litb: I suppose what I meant was that the C++ standard does not specify the existence of an O(1) hash map in the standard template library. This means one cannot assume it exists... however, some implementations of the standard template library have "extras"... things not specified by the standard, but that are there for convenience. hash_map falls into this category. I don't understand what you mean by "avoiding the term STL". If we are talking C++ it's a hard term to avoid.
Tom
He means that technically, "the STL" is the library developed by Stepanov based on his (language-agnostic) ideas about generic programming. What got adopted into the C++ standard library has had some changes applied to it, and many components removed (for example, the "original" STL had a hash map, I believe. Plus, of course, the mysteriously missing copy_if algorithm).So technically, what comes with your C++ compiler is not the STL, but the C++ standard library, part of which happens to be very very similar to the STL
jalf
@Tom, i know what you mean :) But i think it may sound not quite clear to someone that doesn't know that std:: hasn't got a hash map (they could think std::'s hash_map is O(n) or something). @jalf is right about what i mean. Read the 3rd paragraph here, too: http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter02_030.html
Johannes Schaub - litb
Thanks jalf and litb :-). I didn't realize my abuse of terminology.
Tom
+3  A: 

Why can't you use Boost? The Unordered collections library is "Header only", meaning you don't have to pull in Boost's BJam build process and installer. You could just grab the .hpp files and add them to your project.

John Kugelman
Basically I am not allowed to "rip" anything and only use std as standard. Really don't know why I have such a restriction. But I didn't know you could just grab the headers without installing boost.. Thanks for tip !
Milan
+1  A: 

Default STL in the current standard does not have O(1) lookup containers.

antti.huima
I wonder why this is...
Litherum
A: 

As well as hash_map in some STLs, look for unordered_map (which is what it will be called and/or is called in the TR1 version of C++).

ChrisW
A: 

You can use the unordered_map container. Its in tr1 and will be in the next full standard. Visual Studio has an implementation of it in <unordered_map> the and documentation can be found here: http://msdn.microsoft.com/en-us/library/bb982522.aspx

Fire Lancer
+2  A: 

hash_map is part of the SGI extension to the STL. In GCC, you can use it by doing the following; I don't know about other implementations:

#include <ext/hash_map>

using __gnu_cxx::hash_map;

hash_map<int,string> foo; // or whatever

unordered_map is part of the TR1. In GCC, you can use it by doing the following; I don't know about other implementations:

#include <tr1/unordered_map>

using std::tr1::unordered_map;

unordered_map<int,string> foo; // or whatever
newacct
+5  A: 

If you are really restricted to std:: and can't use anything else, std::map is your best bet. This only gives you logarithmic lookup time, not constant one, but compared with arrays/vectors it will be blazingly fast. Also I guess for just 100000 elements the logarithmic lookup will be by fast enough and you won't win much by using a hash table.

That being said, chances are that your implementation already includes some hash table implementation. So if std::map really isn't fast enough, try

#include <tr1/unordered_map>
std::tr1::unordered_map<int,int> test;

or

#include <hash_map>
stdext::hash_map<int,int> test;

or even

#include <boost/tr1/unordered_map.hpp>
std::tr1::unordered_map<int,int> test;
sth
stdext! You just saved me a bunch of searching. Thanks!
Ian Varley