tags:

views:

127

answers:

3

Could you let us know how to use stl:map as two dimension array? I wanted to access the individual elements as like mymap[i][j] where I do not know beforehand what the value of i or j could be. Any better ideas to do the same thing in other way?

+6  A: 

You can do

std::map<int, std::map<int, int> > mymap;

For example:

#include <map>
#include <iostream>

int main() 
{
    std::map<int, std::map<int, int> > mymap;

    mymap[9][2] = 7;
    std::cout << mymap[9][2] << std::endl;

    if (mymap.find(9) != mymap.end() && mymap[9].find(2) != mymap[9].end()) {
        std::cout << "My map contains a value for [9][2]" << std::endl;
    } else {
        std::cout << "My map does not contain a value for [9][2]" << std::endl;
    }

    return 0;
}

prints 7 on the standard output, followed by "My map contains a value for [9][2]".

Andrew Stein
Could you let me know how do I insert an element in this map? Could you provide an example. In my case I would need to store object pointers in the map. Thank you.
Thanks for your reply. Now how to check if there is an element at index i,j?
Updated my answer to show how to insert and extract an int element from the map.
Andrew Stein
Thank you. I wanted to know how to find out if there is a valid element at index i,j? That means I wanted to test the validity of position [i][j] before I try to access the element.
@ebtest, testing for a value at an index is a little more complicated. You have to do it in two steps, check the first index then if it exists use the result to check for the second index, with the `find` member function.
Mark Ransom
Updated the example to show how to check if the map contains an element.
Andrew Stein
@Andrew Stein: +1, but the downfall to your method of checking for existence is that it can't be used from within a const-qualified method (since there is no `operator[] const` for `std::map`).
dreamlax
Could you please explain a little bit?
shouldn't it be `else { cout << "DOESN'T contain value for [9][2]"; }`?
Graphics Noob
@Graphics fixed
Andrew Stein
@dreamlax -- you are quite correct. But I guess I should leave *something* as an exercise for the reader :-)
Andrew Stein
A: 

Consider using a kd-tree instead. Each level of branching will compare the i an j values in turn. See http://en.wikipedia.org/wiki/Kd-tree.

BennyG
+3  A: 

An alternative solution to Andrew Stein's which plays nicer with the rest of STL is to simply use

typedef std::map<std::pair<int, int>, int > AMapT;
AMapT mymap;
mymap[std::make_pair(2, 4)] = 10;
...
AMapT::iterator f = mymap.find(std::make_pair(3, 5));

For example, with this way you don't need to chain two calls to map::find to search for a single value.

Carlos Scheidegger
Can I use this to use as a 3 dimension array?
Worth pointing out that `std::map` requires the key to be less-than comparable. Carlos' solution works because `std::pair` provides a lexicographic less-than comparator. http://www.sgi.com/tech/stl/pair.html
rwong
ebtest, you can, but it gets ugly: `std::map<std::pair<int, std::pair<int, int> >, int>`. You're probably better off with boost's tuple types or just a struct and constructors that you roll your own. As rwong pointed out, you'll also need a less-than comparison operator.
Carlos Scheidegger