2

We can easily convert an array to a vector with the following:

int a[n];

vector<int> b = vector(a, a + n);

I want to work with matrix, what if I want to convert :

int a[n][n];

to

vector<vector<int>> b = ... // from a 

with b.size() = n and b[0...n-1].size() = n ?


Alternatively I am okay with a solution converting

std::vector< std::array<int, n> > a;
a.reserve(n);

vector<vector<int>> b = ... // from a
Antonin GAVREL
  • 9,682
  • 8
  • 54
  • 81
  • 2
    If your matrixes have constant lengths, i.e. are always rectangular, you probably do not need the flexibility of vectors. Not in at least one of the dimensions. – Yunnosch Apr 23 '21 at 14:38
  • Regarding `a.reserve(n)` you should read [Choice between vector::resize() and vector::reserve()](https://stackoverflow.com/questions/7397768/choice-between-vectorresize-and-vectorreserve). `reserve(n)` doesn't do anything meanginful unless you also insert elements. – François Andrieux Apr 23 '21 at 14:40
  • @Yunnosch I agree that is a valid point but I do need it, as I do not have control over the type (need to return a vector>). I coined a solution for https://leetcode.com/problems/spiral-matrix-ii/ using int [n][n]. Hence my question. NB, related: https://stackoverflow.com/questions/18991765/vector-of-vectors-reserve – Antonin GAVREL Apr 23 '21 at 14:40
  • Why not use vectors (or `std::array`) from the start? Why do you need to "convert" to a vector? – Some programmer dude Apr 23 '21 at 14:40
  • I don't think you can do better than using a for loop here. – Peter Apr 23 '21 at 14:40
  • `std::vector` has no feature for "adopting" an existing array. You need to copy the array. `std::vector` has a constructor that accepts a pair of iterators, which should make copying pretty easy at least. – François Andrieux Apr 23 '21 at 14:41
  • Have you considered using a linear algebra lib, such as [xtensor](https://xtensor.readthedocs.io/en/latest/) or [eigen](https://eigen.tuxfamily.org/)? – Taiguara Tupinambás Apr 23 '21 at 14:44
  • 1
    @TaiguaraTupinambás I would like to keep it simple, with only std – Antonin GAVREL Apr 23 '21 at 14:46

1 Answers1

3

I doubt that vector of vector is the best choice of the container for your use case, but if it's out of your control something like this should work:

int a[n][n];
std::vector<std::vector<int>> v;
v.reserve(n);
for (int *arr : a) {
    v.emplace_back(arr, arr + n);
}
Dan M.
  • 3,818
  • 1
  • 23
  • 41
  • If you find this solution give you performance problems, note that `vector`s of `vector`s can be surprisingly slow. Each `vector` is a contiguous block of memory, but here you have `n+1` `vector`s and will have to do a bunch of expensive hopping around in RAM to read all of the data you want rather than reading in one big block. It is often better to make one big `vector` of size `n*n` and wrap it in a class that performs the a little bit of math to map the 2D coordinates to a simple 1D index. [Here's a simple example](https://stackoverflow.com/a/2076668/4581301). – user4581301 Apr 23 '21 at 14:57
  • It's a bit harder to use, so don't use it unless you need the speed. – user4581301 Apr 23 '21 at 14:57
  • @user4581301 the question asked for vector of vectors specifically (and OP clarified in the comments that the choice of the type is out of their control). I've just provided a reasonable solution to that problem. – Dan M. Apr 23 '21 at 14:59
  • @DanM. Thank you and +1, I will give it one day before selecting as answer to see if someone can come up with a solution without any loop (unlikely but we never know) ;) I ended up declaring a vector directly `vector> a(n,vector(n));` https://github.com/agavrel/leetcode/blob/master/bit_manipulation/0059_Spiral_Matrix_II/solution.cpp – Antonin GAVREL Apr 23 '21 at 15:02
  • @AntoninGAVREL you can likely replace the loop with a `std::for_each` but that's just moving it inside a library function. `std::vector>` is no more special than `vector`, so it doesn't have any extra methods/constructors for multidimensional stuff. – Dan M. Apr 23 '21 at 15:06
  • Yes I do agree, there is no need to involve a library function if it is not doing a better job, your solution currently looks like the best approach. – Antonin GAVREL Apr 23 '21 at 15:07