6
vector<vector<int>> sort_a;
vector<int> v2;
vector<int> v3;

for (int i=0; i<4; ++i) {
v2.push_back(i);

  for (int j=0; j<4; ++j) {
  v3.push_back(j);
  sort_a.push_back(v2);
  sort_a.push_back(v3);
  }

}

Vector sort_a should be a 4x4 array, instead the output is 31x1 with lots of empty elements, how do i insert elements in a multidimensional vector ?

Gambit King
  • 483
  • 3
  • 8
  • 18

2 Answers2

9

Don't think of it as a multidimentional vector, think of it as a vector of vectors.

int n = 4;
std::vector<std::vector<int>> vec(n, std::vector<int>(n));

// looping through outer vector vec
for (int i = 0; i < n; i++) {
  // looping through inner vector vec[i]
  for (int j = 0; j < n; j++) {
    (vec[i])[j] = i*n + j;
  }
}

I included parentheses in (vec[i])[j] just for understanding.

Edit:

If you want to fill your vector via push_back, you can create a temporary vector in the inner loop, fill it, and then push_back it to your vector:

for (int i = 0; i < n; i++) {
  std::vector<int> temp_vec;

  for (int j = 0; j < n; j++) {
    temp_vec.push_back(j);
  }

  vec.push_back(temp_vec);
}

However, push_back calls result in slower code, since not only you need to reallocate your vector all the time, but also you have to create a temporary and copy it.

prazuber
  • 1,352
  • 10
  • 26
  • 1
    This will attempt writing beyond the end of the vectors. – interjay Dec 18 '12 at 16:05
  • By reserving elements, i can use [][] method to pass values, but since there was a lot of unwanted allocation i wanted to use pushback and insert values only when needed, how do i do that ? – Gambit King Dec 18 '12 at 16:08
  • @interjay: sorry, for some reason I thought that vectors were already properly resized. – prazuber Dec 18 '12 at 16:08
  • You don't have to resize inside the loop. You can do it all in the initialization. Just make a size 4 vector full of size 4 vectors. – juanchopanza Dec 18 '12 at 16:24
4

a vector<vector<int>> is not the best implementation for a multidimensional storage. The following implantation works for me.

template<typename T>
class array_2d {
    std::size_t data;
    std::size_t col_max;
    std::size_t row_max;
    std::vector<T> a;
public:
    array_2d(std::size_t col, std::size_t row) 
         : data(col*row), col_max(col), row_max(row), a(data)
    {}

    T& operator()(std::size_t col, std::size_t row) {
        assert(col_max > col && row_max > row)
        return a[col_max*col + row];
    }
};

use case:

array_2d<int> a(2,2);
a(0,0) = 1;
cout << a(0,0) << endl;

This solution is similar to the one described here.

Community
  • 1
  • 1
andre
  • 7,018
  • 4
  • 43
  • 75
  • You can initialize vector `a` in the constructor initializer list and thus avoid the call to `rezize`. This could avoid one re-allocation. – juanchopanza Dec 18 '12 at 17:07