3 dimensional vector in c++ - c++

i want to store a vector of objects for a node and subset of set.
so I want to implement a 3 d vector where the first dimension has size #nodes = n and the second dimension has size 2^|set| = m. the last dimension shouldn't have fixed size, because I want to append new objects in my program.
vector< vector < vector<Object>>> Vector3d( n , ( m, ( ( ???)))
what should I write instead of ???
i have tried to use arrays inside of a vector, but I didn't succeed that way.
thank you in advance

The method of initialisation is
vector< vector < vector<Object>>> Vector3d(n,vector<vector<Object>(m))
This will work, as it will initialize the first dimension's size as n, which would contain n no of vector<vector<Object>(m) which is the default value. Now the size of the second dimension is defined as m, which has no initial value, hence you can append any vector to the second dimension space.
i.e.
vector<Object> v;
Vector3d[i][j].push_back(v);
where i and j are the indexes of the first 2 dimensions

Related

How to push queue into a vector of queues when vector size is not constant? [duplicate]

In some cases only the below line works.Why so?
vector< vector<int>> a(M,N);
This works in every case.
vector< vector<int>> a(M, vector<int> (N));
What's the difference?
std::vector has a fill constructor which creates a vector of n elements and fills with the value specified. a has the type std::vector<std::vector<int>> which means that it is a vector of a vector. Hence your default value to fill the vector is a vector itself, not an int. Therefore the second options is the correct one.
std::vector<std::vector<int>> array_2d(rows, std::vector<int>(cols, 0));
This creates a rows * cols 2D array where each element is 0. The default value is std::vector<int>(cols, 0) which means each row has a vector which has cols number of element, each being 0.
For declaring a 2D vector we have to first define a 1D array of size equal to number of rows of the desired 2D vector.
Let we want to create a vector of k rows and m columns
"vector<vector<int>> track(k);"
This will create a vector of size k. Then use resize method.
for (int i = 0; i < k; i++) {
track[i].resize(m);
In this way you can declare a 2D vector

Declaring a 2D vector

In some cases only the below line works.Why so?
vector< vector<int>> a(M,N);
This works in every case.
vector< vector<int>> a(M, vector<int> (N));
What's the difference?
std::vector has a fill constructor which creates a vector of n elements and fills with the value specified. a has the type std::vector<std::vector<int>> which means that it is a vector of a vector. Hence your default value to fill the vector is a vector itself, not an int. Therefore the second options is the correct one.
std::vector<std::vector<int>> array_2d(rows, std::vector<int>(cols, 0));
This creates a rows * cols 2D array where each element is 0. The default value is std::vector<int>(cols, 0) which means each row has a vector which has cols number of element, each being 0.
For declaring a 2D vector we have to first define a 1D array of size equal to number of rows of the desired 2D vector.
Let we want to create a vector of k rows and m columns
"vector<vector<int>> track(k);"
This will create a vector of size k. Then use resize method.
for (int i = 0; i < k; i++) {
track[i].resize(m);
In this way you can declare a 2D vector

Not getting the input values when printing vector of pairs

I want to add a pair to a vector of pairs.
When I print the vector elements, I don't get the integers I input.
Please help.
#include<iostream>
#include<vector>
#include<utility>
using namespace std;
int main()
{
vector<vector<unsigned long int> >matrix;
vector<pair<int,int> >pmat;
int L;
cin>>L;
int n1, n2;
pmat.resize(L);
for(int k = 0; k<L; k++)
{
cin>>n1>>n2;
pair<int,int> p = make_pair(n1,n2);
cout<<p.first<<p.second<<endl;
pmat.push_back(p);
}
for(int k = 0; k<L; k++)
{
cout<<pmat[k].first<<','<<pmat[k].second<<' ';
}
cout<<endl;
return 0;
}
Method 1:
Delete this line:
pmat.resize(L);
You don't need to resize it in the first place as you do push_back() when adding afterwards.
Method 2:
Change the following line
pmat.push_back(p);
to
pmat[k] = p;
You can do resize() in the first place, but after this, you should not use push_back() when adding, just use pmat[k] = p.
PS: you should not mix these two ways up. Always use one of them consistently.
Since you're using pmat.resize(L) and L times pmat.push_back(...), you're ending up having stored 2 * L entries in your vector. However you're printing just the first half, index 0 to L - 1. The values you want are stored from index L to 2 * L - 1.
Just change pmat.resize(L) to pmat.reserve(L).
Alternatively, you can use the resize(L), but to end up with L entries, you need to store each input pair to pmat[k], hence you write pmat[k] = p;.
As a rule of thumb, I recommend using the reserve + push_back approach if you know how many elements you're going to add. The reason is, that resize initializes the elements, while reserving just asserts that there will be enough space and no reallocation will be necessary with any following push_back.
You don't want to add more pairs after you allocated them. You can now directly access them.
Just use pmat[k] = p; instead of pmat.push_back(p);
If you print the size of the vector after reading the values, you will notice a small problem with your program:
./test
2
1 2
12
3 4
34
Size of the vector: 4
0,0 0,0
Huh? Even though I only entered 2 pairs, the size of the vector is 4. How did this happen?
If you look at the documentation for resize, it says
Resizes the container to contain count elements.
So even before you read any values, your vector will already contain 2 elements! Those will be default-constructed and therefore be 0. When you then push_pack the elements you read in, those will land at the indices 2 and 3 in the vector, so the end vector has twice as much elements as you wanted (4 in this case). You only print out the first half, which are the zero values.
The solution is to use reserve instead of resize, which doesn't create the elements but only reserves space for them, or just delete the call to resize. Using reserve is more efficient though, because then the vector will only need to allocate memory once.
pmat.resize(L);
if vector in empty its going to initialize a vector pmat with size L then assign default values to vector so now pmat size is L with default values
for(int k = 0; k<L; k++)
{
cin>>n1>>n2;
pair<int,int> p = make_pair(n1,n2);
cout<<p.first<<p.second<<endl;
pmat.push_back(p);
}
then u r pushing values to pmat L times so the final size is 2*L
for(int k = 0; k<L; k++)
{
cout<<pmat[k].first<<','<<pmat[k].second<<' ';
}
here u r going to read from 0 to L-1 , it contains default values you can see your values from L-1 to 2L-1.
so finally what i want say is use reserve instead of resize
or
pmat.resize(L); comment this line

Initialzing a 2d vector in C++

I know that you can initialize a 1d vector with some value in the following way:
vector<int> vec(10, 100); //creates a vector of size 10 and each element = 100
Now I would like to do the same thing with a 2d vector. I know the following would give an error, because the size of columns is not specified:
vector<vector<int> > vec(10, 100);
So, is there any way to accomplish this? Also, I want to keep the column size same for each vector in the 2d vector (i.e., an nxn grid).
Or maybe I can use the "std::fill()" function in some way to accomplish this? And can this functionality be extended to an nxm grid?
vector<vector<int>> vec(10, vector<int>(10, 100));
// n m value
This will create a vector of 10 vectors of size 10 and with elements initialized to 100.

Combinations of Multiple Vector's Elements Without Repetition

I have n amount of vectors, say 3, and they have n amount of elements (not necessarily the same amount). I need to choose x amount of combinations between them. Like choose 2 from vectors[n].
Example:
std::vector<int> v1(3), v2(5), v3(2);
There cannot be combinations from one vector itself, like v1[0] and v1[1]. How can I do this?
I've tried everything, but cannot figure this out.
If I understand you correctly you have N vectors, each with a different number of elements (call the size of the ith vector Si) and you which to choose M combinations of elements from these vectors without repetition. Each combination would be N elements, one element from each vector.
In this case the number of possible permutations is the product of the sizes of the vectors, which, for lack of some form of equation setting I'll call P and compute in C++:
std::vector<size_t> S(N);
// ...populate S...
size_t P = 1;
for(size_t i=0;i<S.size();++i)
P *= S[i];
So now the problem becomes one of picking M distinct numbers between 0 and P-1, then converting each of those M numbers into N indices into the original vectors. I can think of a few ways to compute those M numbers, perhaps the easiest is to keep drawing random numbers until you get M distinct ones (effectively rejection sampling from the distribution).
The slightly more convoluted part is to turn each of your M numbers into a vector of indices. We can do this with
size_t m = /* ... one of the M permutations */;
std::vector<size_t> indices_m(N);
for(size_t i=0; i<N; ++i)
{
indices[i] = m % S[i];
m /= S[i];
}
which basically chops m up into chunks for each index, much like you would when indexing a 2D array represented as a 1D array.
Now if we take your N=3 example we can get the 3 elements of our permutation with
v1[indices[0]]
v2[indices[1]]
v3[indices[2]]
generating as many distinct values of m as required.
Probably the confusion rises from improper definition of the problem. Guessing that you need to N times pick 1 element from 1 of V vectors, you can do this:
select N of the V vectors you want to pick from (N <= V)
for each of the selected vectors, select 1 of the vector.size() elements.