Vector Initialization Vector

I have a hard time when my head wrapped around how to initialize a vector of vectors.

typedef vector <vector <vector <vector <float β†’ β†’ DataContainer;

I want it to fit

level_1 (2 elements/vectors) level_2 (7 elements/vectors) level_3 (480 elements/vectors) level_4 (31 elements of float) 

Addressing items is not a problem. It should be as simple as something like

 dc[0][1][2][3]; 

The problem is that I need to fill it with data that crashes from the file, so the following elements should be placed as

 dc[0][3][230][22]; dc[1][3][110][6]; //...etc 

Therefore, I need to pre-initialize V of V.

I feel myself or is it as simple as

 for 0..1 for 0..6 for 0..479 for 0..30 dc[i][j][k][l] = 0.0; 

It does not seem to work. One way or another, top-level vectors must be initialized first.

Any help appreciated. I am sure it should be easier than I imagine.

+6
c ++ initialization vector deserialization
source share
3 answers
  • Please do not use nested vectors if the size of your storage is known in advance, i.e. there is a specific reason why, for example, the first index should be 6 and will never change. Just use a simple array. Even better, use boost::array . Thus, you get all the benefits of having a simple array (saving a huge amount of space when you go multi-dimensional), and the benefits of having a real instance of the object.

  • Do not use nested vectors if your repository should be rectangular, i.e. you can resize one or more parameters, but each "line" should have the same length at some point. Use boost::multi_array . Thus, you document "this storage is rectangular", save a huge space and still get the opportunity to change the size, the benefits of having a real object, etc.

The thing about std::vector is that it (a) is designed to resize and (b) does not care about its contents in the least if they are of the correct type. This means that if you have vector<vector<int> > , then all β€œrow vectors” must keep their own separate accounting information about how long they are, even if you want to ensure that they are the same length . It also means that they all manage separate memory allocations, which degrades performance (cache behavior) and consumes even more space due to the way std::vector reallocates. boost::multi_array designed to allow you to resize it, but you will not constantly resize it by adding elements (strings, for a two-dimensional array / faces, for a 3-dimensional array / etc.) to the end. std::vector intended for (potentially) waste, to make sure that the work is not slow. boost::multi_array designed to save space and keep memory neat.

It is said :

Yes, you need to do something before you can index the vector. std::vector will not lead to magical actions for indexes to appear because you want to store something there. However, this is easy to handle:

You can initialize the vector with the desired zeros by default, and then replace them using the constructor (size_t n, const T& value = T()) . I.e

 std::vector<int> foo(10); // makes a vector of 10 ints, each of which is 0 

because the "built by default" int has a value of 0.

In your case, we need to specify the size of each dimension by creating a sub-vector corresponding to the size and allowing the designer to copy them. It looks like this:

 typedef vector<float> d1; typedef vector<d1> d2; typedef vector<d2> d3; typedef vector<d3> d4; d4 result(2, d3(7, d2(480, d1(31)))); 

Thus, an unnamed d1 is created from size 31, which is used to initialize the default d2 , which is used to initialize the default d3 , which is used to initialize the result .

There are other approaches, but they are much clumsy if you just want a bunch of zeros to start. If you are going to read the entire data set from a file, though:

  • You can use .push_back() to add to a vector. Create an empty d1 just before the inner loop loop in which you re .push_back() to populate it. Right after the loop, you .push_back() result on d2 that you created immediately before the next-inner loop, etc.

  • You can first resize the vector using .resize() and then index it in the usual way (to the size you resized by).

+16
source share

EDIT: I admit that this code is not elegant. I like @Karl's answer, which is the right way.

This code has been compiled and tested. He printed 208320 zeros that are expected (2 * 7 * 480 * 31)

 #include <iostream> #include <vector> using namespace std; typedef vector< vector < vector < vector< float > > > > DataContainer; int main() { const int LEVEL1_SIZE = 2; const int LEVEL2_SIZE = 7; const int LEVEL3_SIZE = 480; const int LEVEL4_SIZE = 31; DataContainer dc; dc.resize(LEVEL1_SIZE); for (int i = 0; i < LEVEL1_SIZE; ++i) { dc[i].resize(LEVEL2_SIZE); for (int j = 0; j < LEVEL2_SIZE; ++j) { dc[i][j].resize(LEVEL3_SIZE); for (int k = 0; k < LEVEL3_SIZE; ++k) { dc[i][j][k].resize(LEVEL4_SIZE); } } } for (int i = 0; i < LEVEL1_SIZE; ++i) { for (int j = 0; j < LEVEL2_SIZE; ++j) { for (int k = 0; k < LEVEL3_SIZE; ++k) { for (int l = 0; l < LEVEL4_SIZE; ++l) { dc[i][j][k][l] = 0.0; } } } } for (int i = 0; i < LEVEL1_SIZE; ++i) { for (int j = 0; j < LEVEL2_SIZE; ++j) { for (int k = 0; k < LEVEL3_SIZE; ++k) { for (int l = 0; l < LEVEL4_SIZE; ++l) { cout << dc[i][j][k][l] << " "; } } } } cout << endl; return 0; } 
+1
source share

You may have to set the size or backup memory

Could you make a call for each or nested for him

 myVector.resize(x); //or size 

at every level.

0
source share

All Articles