How .push_back works in C++? - c++

I have a question in my mind. Lets say I have two vectors called vector1 and vector2.
vector <int> vector1{1,2};
vector <int> vector2{3,4};
Now I want to create a 2-D vector called vector_2d and assign these two vectors into my new 2-D vector using push_back function.
vector <vector <int>> vector_2d;
vector_2d.push_back(vector1);
vector_2d.push_back(vector2);
How C++ decides to assign the vector2 to the second row of the vector_2d? Why it didn't add these two vectors back to back?
Also I tried to add the vector1 multiple times to a new 2-D vector called new_vector. But it seems to be add vector1 only once. Why is this the case? Why it didn't add multiple vector1 to new rows or back to back?
vector <vector <int>> new_vector;
new_vector.push_back(vector1);
new_vector.push_back(vector1);
new_vector.push_back(vector1);
new_vector.push_back(vector1);

How C++ decides to assign the vector2 to the second row of the vector_2d?
By reading your code.
You're adding two "inner" vectors to your outer vector, resulting in two elements.
That's what happens when you call push_back on the outer vector.
Why it didn't add these two vectors back to back?
Because you didn't tell it to.
That would be:
vector <vector <int>> vector_2d;
vector_2d.push_back(vector1);
std::copy(std::begin(vector2), std::end(vector2), std::back_inserter(vector_2d[0]));
Also I tried to add the vector1 multiple times to a new 2-D vector called new_vector. But it seems to be add vector1 only once. Why is this the case?
It isn't.
Why it didn't add multiple vector1 to new rows or back to back?
It did. You must have observed it wrong somehow.

Related

How to create vectors dynamically in C++

I am trying to initialize vectors depending upon user input. For example, if user provide n=4 then I have to create 4 vectors of varying sizes.
As for vectors syntax is :
vector<int> v1(x);
So, similarly I want to create v2,v3 and v4 named vectors.
I am confused. How can I do this ?
The names of individual vectors v1, v2, v3, ... are defined at compile time. If you want to have a dynamic number of vectors, you need a vector of vectors, e.g.:
std::vector<std::vector<int>> vs;
or if you already know the number of vectors n that you want:
std::vector<std::vector<int>> vs(n);
Then, instead of using v1, v2, v3, you'd use vs[0], vs[1], vs[2], and your code could use dynamically a vector v[i] where i is a variable or an expression.
You can add a vector to vs with emplace_back/push_back or resize:
vs.emplace_back();
//or
vs.push_back({});
// or
vs.push_back(std::vector<int>());
// or
vs.resize(4);
In the latter case vs will contain four empty vectors (or the first 4 existing vectors if vs already had more than 4 vectors).
And you can add elements to the inner vectors as usually, e.g.:
vs[0].push_back(42);
vs[2].resize(x);
After that the first vector will have length one and the third vector will have length x.
Or you can insert a vector with size x directly after the last vector:
vs.emplace_back(x);
// or
vs.push_back({x});
// or
vs.push_back(std::vector<int>(x));
Elements can then be accessed with double indices, e.g.
vs[1][14]
reads the 15th element of the 2nd vector.

Why was a change in vector not reflected in a 2D vector?

I'm new to vectors.
I have two vectors, vector1 and vector2, both have two values each. Now, using these two vectors, I have made a 2 dimensional vector, vector_2d whose value(contents) I want to print. I use the below code and everything works fine.
vector<int> vector1;
vector<int> vector2;
vector1.push_back(10);
vector1.push_back(20);
vector2.push_back(100);
vector2.push_back(200);
vector_2d.push_back(vector1);
vector_2d.push_back(vector2);
cout<<"The elements in vector_2d are: "<<vector_2d.at(0).at(0)<<" "<<vector_2d.at(0).at(1)<<" "<<vector_2d.at(1).at(0)<<" "<<vector_2d.at(1).at(1)<<endl;
Now, I want to replace the first value in vector1 (which is 10) with 1000. I do it by a simple assignment operator:
vector1.at(0) = 1000;
Now, I try to print vector1 and vector_2d again. I get the result that I expected with vector1:
cout<<vector1.at(0)<<endl; //1000
But when I print vector_2d, I get the same result as before. The changes done in vector1 are not being reflected in the 2D vector. Why is this happening?
The value in your 2D vector is not changed, because while pushing back 1D vectors
vector_2d.push_back(vector1);
vector_2d.push_back(vector2);
you made copies of each of them. Therefore, changing values in vector1 will not change the values in its copy stored as element 0 of vector_2d. If you would like to change the values in 2D vector, you can do it directly:
vector_2d.at(0).at(0) = 0;
Another possibilities were mentioned in the comments to your question (like having a vector of pointers or references), but I do not recommend those because of possible memory violations (e.g. if your 2D vector will live longer than 1D vectors that are referenced).

How to copy a row of 2D Vector to a 1D vector?

How should I initialize copyRow with first row of holder_node?
I came up with the following code.
vector<vector<double>> holder_node;
vector<double> copyRow(initial_values[0].begin(), initial_values[0].end());
You can access an element of a vector (even if the element again is a vector) through array subscription / through an index:
vector<double> copyRow = holder_node[0];
Note that a vector is not just a pointer to some memory; it can distinguish copying from moving and behaves correctly in each case. Above statement triggers a copy.

dynamically changing name of an array in c++

Hi I have a problem where at compile time, I don't know how many vectors in my program are needed. The number required depends on a data set given at run-time, which will results in the range of vectors needed to be from 1 to N.
So if the data set requires ten vectors, it will create vec1,vec2,......vecN
How can i dynamically create the vectors so that they all have a different name?
I would then need to call each array separately. Presumably
I could just use strings and a few loops for this.
You can't do that directly. However, you could use a map to store a vector name, and the vector itself:
map<string, vector<int> > myMap;
You can add elements simply like this (if the element with such key doesn't exist yet):
vector<int> vec;
myMap["vec"] = vec;
If you'll do it with a key that already exists, the value will be replaced. For example:
vector<int> vec;
vector<int> vec1;
myMap["vec"] = vec;
myMap["vec"] = vec1;//now myMap["vec"] holds the vec1 vector
You can also easlly access elements like this:
myMap["vec"]//this will access the vector with the key "vec1"
You can create a vector to contain your vectors:
std::vector<std::vector<int>> my_vector_of_vectors;
// Add a vector
my_vector_of_vectors.push_back(std::vector<int>{});
// Add a number to the inner vector
my_vector_of_vectors[0].push_back(1);
you have a vector of vectors, vec[0] to vec[n], each one containing the vector.
However, this works est if you know the number of vectors (eg 10). If you need to add new ones on-demand, then a list of vectors or a map might be a better option for you.

push_back vector of vector

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.