push_back vector of vector - c++

i got some problem with vector of vector. in my program, i have defined a dynamic memory for vector of vector and did the resize and push_back the elements.
vector<vector<double> > *planes = new vector<vector<double> >
planes->resize(s_list->size()); // size of another vector that i need to use
vector<int>::iterator s_no;
for(s_no=s_list->begin(), int i=0; s_no!=s_list->end(); s_no++, i++){){
//where i i the indices of planes
//some codes for computing length, width
planes->at(i).push_back(lenght);
planes->at(i).push_back(width);
}
it works and i got the print of all values what i added. then, i changed new vector defining part as follows
vector<vector<double> > *planes =
new vector<vector<double> >(s_list->size(),vector<double>(2,0.0))
and removed the resize part. then, when i got the print out of vector of vector, i got 0 values for all. could you please rectify this issue.

Use at instead of push_back
planes->at(i).at(0)=lenght;
planes->at(i).at(1)=width;
push_back() adds new items, therefore you end with with 4 items in each vector. You should use at() to modify the existing entries.
Better still is to use a vector< pair<double,double> >, assuming you will always have two items.

Related

Vector Vector C ++

Vector Vector C ++
Hi, I do not understand the syntax of nested vectors to simulate an array, I have the following code.
vector< vector< float> > myvector (n, vector < float> (2));
But I do not quite understand how it works, especially where you specify the size of the vectors and the vectors in it, if you want to make a resize so that my vector vector has specified dimensions how can I resize internal vectors?
Something like changing vec [10] [2] to vec [10] [5] (changing the second dimension)
In addition to how to make copies with multidimensional vectors something like:
vector< int> myvector (myVectorToCopy, myVectorToCopy+myVectorToCopy.size());
But with several dimensions.
Thanks.
vector<vector<float>> means you are creating a vector which contains a vector of floats. The constructor argument means you are creating a vector of size n where each element of vector is a vector of floats having size 2.
To resize the vector<vector<float>>:
for (int i = 0; i < n; ++i)
A[i].resize(newSize);
Alternatively you could use:
A.assign(n,vector<float>(newSize));
To make a copy of multidimensional vector use constructor:
vector<vector<float>> B(A);
Vectors in C++ will resize automatically if you fill them up and try to add more to them. If you know the exact size of your vector, I would suggest switching to std::array, however you will lose the ability to resize them at runtime.
std::vector::operator[] has an overload to return a reference to the T used to create the template (in your case T is std::vector, the nested one). If you know the index in the outer vector, you could do something like:
myVec[0].resize(5);
This will resize your nested vector at position 0 to 5 elements.
Copying is much the same as accessing:
std::copy(std::begin(VecToCopy), std::end(VecToCopy), std::begin(VecToFill));
Using std::begin last might not be what you want but its just an example.
http://en.cppreference.com/w/cpp/algorithm/copy
http://en.cppreference.com/w/cpp/container/array

How do I initialize and fill a vector of type vector<vector<int> >?

I am trying to return a write a function that creates a vector<vector<int> > and fills it and returns it. I am facing segmentation fault when trying to push elements into a vector<vector int>. Can anyone help me with this problem?
vector<vector<int> > Solution::prettyPrint(int A)
{
vector<vector<int>> arr;
for(int x=1;x<(2*A);x++)
{
for(int y=1;y<(2*A);y++)
{
int xp=x,yp=y;
if(x>A) xp=2*A-x;
if(y>A) yp=2*A-y;
int min=(xp<yp)?xp:yp;
arr[x-1].push_back(A+1-min);
}
}
return arr;
}
arr[x-1].push_back(A+1-min);
You are trying to access arr[x-1], but arr is an empty vector at that moment.
Since you know that arr is going to be of size 2*A-1 (at least that is what comes out from your code), you can put a
arr.resize(2*A-1); before the beginning of the outer loop, or directly when declaring it:
vector<vector<int> > arr(2*A-1);
You can go further and initialize even the inner vectors:
for(int x=1;x<(2*A);x++)
{
arr[x-1].resize(2*A-1);
for(int y=1;y<(2*A);y++)
and substitute
arr[x-1].push_back(A+1-min);
with
arr[x-1][y-1]=(A+1-min);
You need to do (assuming your matrix is of size ROWS x COLS)
vector<vector<int>> arr(ROWS, vector<int>(COLS));
and there is no more need for push_back anymore. The whole memory for the 2D array is now reserved so you can just use arr[i][j] to write into it. The code is also a bit faster than using push_back, since push_back does slow re-allocations when it needs to resize the vector.
However try avoiding such nested vectors as they are slow. Use a flat vector instead and map from 2D to 1D and vice versa.
That's right don't go in complex structures save your time and energy and make your project faster. Take a 2D array instead of push_back use arr[i][j]

Difference between vector <int> V[] and vector< vector<int> > V

vector <int> V[] and vector< vector<int> > V both are 2D arrays.
But what is the difference between them and where do we use each one? Please give a brief explanation.
vector<int> V[] is an array of vectors.
vector< vector<int> > V is a vector of vectors.
Using arrays are C-style coding, using vectors are C++-style coding.
Quoting cplusplus.com ,
Vectors are sequence containers representing arrays that can change in
size.
Just like arrays, vectors use contiguous storage locations for their
elements, which means that their elements can also be accessed using
offsets on regular pointers to its elements, and just as efficiently
as in arrays. But unlike arrays, their size can change dynamically,
with their storage being handled automatically by the container.
TL;DR:
When you want to work with a fixed number of std::vector elements, you can use vector <int> V[].
When you want to work with a dynamic array of std::vector, you can use vector< vector<int> > V.
One difference would be that although both can be initialized in the same way, e.g.
vector<int> V1[] {{1,2,3}, {4,5,6}};
vector<vector<int>> V2 {{1,2,3}, {4,5,6}};
and accessed
cout << V1[0].back() << endl;
cout << V2[0].back() << endl;
the V1 can't grow. You cannot make V1.push_back(...) as its not a vector object. Its just an array. Second one is dynamic. You can grow it as you please.
vector<vector<int>> v(26); is a vector containing vectors. In this example, you have a vector with 26 vectors contained in it. The code v[1].push_back(x) means that x is pushed back to the first vector within the vectors.
vector<int> a[26]; is an array of vectors. In other words, a one-dimensional array containing 26 vectors of integers. The code a[1].push_back(x); has x being pushed back to the first index of the array.
vector<int> v[] is an array of vectors. That is, it is an array which contains vectors as its elements.
So, you cannot change the size of the array part, but we can add to its elements which is vector.
For example,
1.vector<int> v1[] = {{1},{2},{3}}; // array that contains 3 vector elements.
2.vector<vector<int>> v2 = {{1},{2},{3}}; // vector that contains 3 vector elements.
So for the first we cannot change the size of v but we can add or delete elements to its elements since it is a vector.
v1.push_back(4); // this will give an error since we cannot the predefined size of array.
v1[1].push_back(4); // this is acceptable since we are changing the vector part.
This makes the v1 {{1},{2,4},{3}}
For the second one, we can change both the overall size and its elements.
v2.push_back(4); // this is acceptable since it is vector.
vector V[] is just a fixed array; and so you can add/modify only till the upper limit. It is not a vector per se, and so has a fixed size limit.
However vector< vector > V is a dynamic vector and its size can be increased dynamically.

Why can't we input a vector as we input an array in C++?

The wiki says:
The elements of a vector are stored contiguously. AND
Vectors allow random access; that is, an element of a vector may be referenced in the same manner as elements of arrays (by array indices).
So why can't we input the elements of a vector as:
vector<int> v;
for(int i=0;i<3;i++)
{
cin>>v[i];
}
Either you need to resize the vector upfront - as other answers say - or you can use C++ standard library. Then the equivalent of your for loop is the following one line:
copy_n(istream_iterator<int>(cin), 3, back_inserter(v));
and it takes care of allocation/resizing.
Your vector has zero elements right now. Try allocating it some space as:
vector<int> v(5);
Then your method would work.
The problem is that you need to allocate the elements of the vector first. So try vector<int> v(4);, so it will start with 4 elements. Then you can load values into them.

Inserting elements into 2D vector

so I'm creating a class that implements an adjacency list. Currently in my class definition I initialized two vectors:
vector<vector<int>> adjList;
vector<int> neighbors;
and I declared two functions that I plan to use to make it:
bool constructAdjList();
bool insertIntoAdjList(int, int);
It's getting difficult wrapping my head around 2D vectors. I understand that it is essentially a vector of vectors, but I'm confused about how to insert a new value into one of the "subvectors". For example, I am able to create an adjacency list in createAdjList that is empty with the following loop:
for (int i = 0; i < numOfValues; i++){
neighbors.push_back(0);
adjList.push_back(neighbors);
neighbors.clear();
}
But how can I say, push_back the value 5 to the 4th vector in adjList, which would be represented in my insertIntoAdjList function as
insertIntoAdjList(4, 5);
I know I can access a specific value in a 2D vector by saying adjList[4][1], but how can I push one onto it?
Thanks!
To push on the vector that is an element of another vector, you simply do this
adjList[x].push_back();
If initially you do not have any values in the vector -
You can push values into one vector and then push this vector into the 2D vector.
For example:
vector< vector<int> > vt1;
vector<int> vt2;
vt2.push_back(value);
vt1.push_back(vt2);
If your vector is already populated then -
vt1[index].push_back(value);
A couple of notes here.
Your loop can be significantly shortened just be using the constructors of your two members:
vector<int> neighbors(1, 0); // set to length 1, value is zero
vector<vector<int>> adjList(numOfValues,neighbors); // "outer" vector is numOfValues long
. // each row is a *COPY* of neighbor
If you can't do this at construction time (maybe numOfValues isn't known yet), then there's still a better loop phrasing we can use:
// neighbors object can be reused
neighbors.clear(0);
neighbors.push_back(0);
adjList.reserve(numOfValues); // reserving memory ahead of time will prevent allocations
for (int i = 0; i < numOfValues; i++){
adjList.push_back(neighbors); // push_back is by *COPY*
}
In your example, by using clear and push_back to essentially build the same vector every loop iteration, you are risking an allocation and deallocation each iteration. In practice, most implementations won't do this, but if we can both shorten and potentially make things more efficient, we may as well.
Lastly, if the number of neighbors is relatively small and similar row to row (for instance a finite elements code with tetrahedral elements, where each element connects to ~5 others), then as others have suggested you may be better off with a different structure than vector-of-vector. For instance, a single vector that is logically organized such that a new "row" begins every N elements.