How to create vectors dynamically in C++ - 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.

Related

How .push_back works in 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.

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).

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.

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.