5

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?

user243655
  • 7,749
  • 8
  • 30
  • 33

3 Answers3

26

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
  • 12,880
  • 5
  • 35
  • 43
  • 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. – user243655 Aug 03 '10 at 02:43
  • Thanks for your reply. Now how to check if there is an element at index i,j? – user243655 Aug 03 '10 at 02:47
  • 2
    Updated my answer to show how to insert and extract an int element from the map. – Andrew Stein Aug 03 '10 at 02:52
  • 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. – user243655 Aug 03 '10 at 02:56
  • @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 Aug 03 '10 at 02:57
  • Updated the example to show how to check if the map contains an element. – Andrew Stein Aug 03 '10 at 02:59
  • 1
    @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 Aug 03 '10 at 03:05
  • Could you please explain a little bit? – user243655 Aug 03 '10 at 03:22
  • shouldn't it be `else { cout << "DOESN'T contain value for [9][2]"; }`? – Graphics Noob Aug 03 '10 at 05:28
  • @dreamlax -- you are quite correct. But I guess I should leave *something* as an exercise for the reader :-) – Andrew Stein Aug 03 '10 at 13:40
9

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
  • 1,906
  • 1
  • 13
  • 18
  • Can I use this to use as a 3 dimension array? – user243655 Aug 03 '10 at 03:30
  • 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 Aug 03 '10 at 04:04
  • ebtest, you can, but it gets ugly: `std::map >, 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 Aug 03 '10 at 04:53
0

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.

BenG
  • 1,292
  • 8
  • 11