1

I'm working on a map generator. I'm using a 2-d vector to keep the data.

Header:

class MapGenerator
{
public:
     ...
protected:
    std::vector< std::vector<int> > map;
...
}

It's size is known once the MapGenerator is instanciated, I was wondering if there was a cleaner way to size it properly and fill it with 0's than what I currently do :

MapGenerator::MapGenerator(int dimensionX, int dimensionY) 
: dimensionX(dimensionX), dimensionY(dimensionY)
{
    map.resize(dimensionX);

    for(int i = 0 ; i < map.size() ; i++)
    {
       map[i].resize(dimensionY);
       fill(map[i].begin(), map[i].end(), 0);
    }

}

This code work's fine, but if there's a cleaner or more optimal approach I'd like to know. I'm using GCC under MinGW and I don't think I have C++ 11 enabled.

Patrick.SE
  • 4,444
  • 5
  • 34
  • 44
  • 2
    Sure, use a member initializer. `: map(dimensionX, std::vector(dimensionY))` All values are 0 after that. – chris Dec 02 '12 at 19:20
  • You can use a 2d array. See "The Boost Multidimensional Array Library" http://www.boost.org/doc/libs/1_52_0/libs/multi_array/doc/user.html – Martin Drozdik Dec 02 '12 at 19:21

3 Answers3

2

I'd start with a 2D array class, something like this:

template <class T>
class array_2D { 
    std::vector<T> data;
    size_t cols;
public:
    array_2D(size_t x, size_t y) : cols(x), data(x*y) {}

    T &operator()(size_t x, size_t y) { return data[y*cols+x]; }
};

There's no need to explicitly zero-fill it. When you create or resize a std::vector, you pass a value that will be used to fill the new "empty" spaces. If you don't pass another value explicitly, it'll use T(), which will work out to 0 in the case of built-in arithmetic types (short, int, long, etc.)

Note that as written, this uses parentheses for addressing (like Fortran or BASIC), so to create a 2D array and fill it with random numbers, you could do something like this:

array_2D<int> x(10, 10);

for (int i=0; i<10; i++)
    for (int j=0; j<10; j++)
        x(i, j) = rand();

It's possible to write a class that does 2D addressing using x[i][j] syntax, but it's enough more complex that unless you're really set on that syntax, it's easier to avoid it. If You really want that, you can see an example (with a 3D array class) in an older answer.

Community
  • 1
  • 1
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
1

Without complicating things by using an additional class for the map itself, this seems to be the simplest way.

If you are looking to avoid that "fill" function call, you may want to see if the line

fill( map[i].begin(), map[i].end(), 0)

can be replaced by a loop of your own, such as"

for(int j = 0 ; j < map[i].size() ; j++){ map[i][j] = 0;}

It may not increase your time complexity, but it will likely have an effect on your space complexity.

0

resize has a second parameter that is the value to fill with. An explicit map[i].resize(dimensionY, 0) is enough.

filmor
  • 30,840
  • 6
  • 50
  • 48