vector of vectors push_back - c++

I'm designing a multilevel queue process simulator in C++ but I've got a problem when trying to implement several queues (my queues are vectors).So,
"multilevel" is a 4 elements array (not vector). Inside each of those elements there is a vector (type t_PCB).
vector<vector<t_PCB>> multilevel[4];
My question is: How can i insert an element at the end of one these 4 t_PCB vectors? Thank you in advance.
I've tried the code line below but it doesn't work (error: not matching member function for call 'push_back')
multilevel[0].push_back(p); //where "p" is a t_PCB object
The line from above can not be used when talking about "multilevel" because this array only accepts arguments type: vector < t_PCB >
So, as I ask at the beginning: how can I push an object type "t_PCB" inside "multilevel"?

By doing this:
vector<vector<t_PCB> > multilevel[4];
You declare an array of four zero-sized vectors, each of which can contain objects of type vector<t_PCB>. What you probably wanted to do is rather:
vector<vector<t_PCB> > multilevel(4);
// ^^^
This will instantiate a vector of four default-initialized objects of type vector<t_PCB>. Then, you can just do:
multilevel[size].push_back(p);
Notice, though, that vector indices (like array indices) are zero-based, so size must be less than the size of the vector.
In the above expression, the sub-expression multilevel[size] returns a reference to the size-th vector inside multilevel, and on that vector you are then invoking the member function push_back(p), which appends element p to it.

Declaring a two dimensional vector is similar to declaring an array. You can also use it in same way...
vector<vector<int> > vec;
for(int i = 0; i < 5; i++)
{
vector<int> row;
vec.push_back(row);
}
vec[0].push_back(5);
cout << vec[0][0] << endl;

You are creating a array of vector<vector<t_PCB>> instead of a single object.
I think the right way to do what you want is:
vector<vector<t_PCB>> multilevel(4);
multilevel[0].push_back(p)

You can create a vector instead of array:
std::vector< std::vector<t_PCB>> multilevel(4); // 2 dim array, 1st dim is 4
and then you can push_back at the end of the vector indexed with WHICH this way:
multilevel[WHICH].push_back(p)

And just to put it out there, to access the vector of vectors:
multilevel[outer][inner]
where outer will return the vector at that index and further indexing
with inner will return the t_PCB object. You could also replace the array-style indexing with the .at() function for bounds checks.

vector<vector<int>> vec; // declare 2D vector
for (int i=0; i<=3; i++) {
vector<int> row; // create a row vector which adds a row to vec
for (int j=0; j<=4; j++) {
row.push_back(j*10); // push elements 0,10,20,30,40 to row
}
vec.push_back(row); // add this row to vec
// Repeat this procedure 4 times to make a 4*5 2D vector
}
cout<<"output is "<<vec[2][4]; // output is 40

Related

What does this line means(in cpp context) list[i].push_back(adj[i][j]);

What does this line means: list[i].push_back(adj[i][j]); ?
vector<vector<int>>printGraph(int V, vector<int> adj[])
{
vector<vector<int>>list(V);
for(int i=0;i<V;i++)
{
list[i].push_back(i);
for(int j=0;j<adj[i].size();j++)
{
list[i].push_back(adj[i][j]);
}
}
return list;
}
In your case, adj is a pointer to a vector(and in this case, I suspect it should be taken as a two-dimensional array), and list is just a vector of vectors, and therefore a two-dimensional array. list[i] is simply a reference to the i-th row of the array list, adj[i][j] is a reference to the value stored in cell [i][j] of the two-dimensional array adj. The push_back method simply adds the passed value to the end of the corresponding vector, which means the expression list[i].push_back(adj[i][j]); will simply add the value stored in the cell adj[i][j] to the end of the line list[i]
Defining a function that return a nested vector as output. The variable list was defined as nested vector in function and as general explanation i could say that two dimensional array represent as vector of vectors in addition with the index of row in the first position of inner peer vector. And the statement:
list[i].push_back(adj[i][j]);
add the elements of two dimensional array to inner vector i'th. push_back method add an element to end of vector.
list[i].push_back(adj[i][j]);
Here list is the vector of vectors (2D array) that is going to store the adjacency list.
Example-
list[1] = [2,3]
list[2] = [1,3]
list[3] = [1,2]

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]

How to give a size to a vector array?

Hello I would like to set 18 elements in my vector array but i'm unsure on how to do it exactly. Would it be like this?
vector<byte> Clients(18);
or like this?
vector<byte> Clients[18];
Vectors are not called vector arrays. They are usually implemented as arrays in the background, but that doesn't change what they are called.
To answer your question, to change the size of a vector you can use the resize member function.
std::vector<int> myvector;
myvector.resize(5);
You can also use resize to initialize all the values. For instance, in the following example there are five 0's in the vector.
std::vector<int> myvector;
myvector.resize(5, 0);
Usually, you just push things into a vector and don't have to set a size. For example:
std::vector<int> myvector;
for (int i = 0; i < 5; i++) {
myvector.push_back(
}
// you now have a vector with a size of 5 that has initialized
// values at indices 0 through 4, inclusive.

Initializing and setting a vector<int>

vector<int> v;
v.push_back(0); //you have to do this
//v[0] = 0; //this gives you an error
v[0] = 1000000; //but now you can set it
So, how come the first time you initialize a vector, you have to push_back, and after that you can just set it? For a primitive type, say int, you can do int i = 0; for initialization.
If you know in advance the size of your vector, definitively don't use a plain sequence of push_back()'s, since it may be a waste of time reallocating if your vector is large (say, >512 elements).
Better do:
OPTION 1: Preallocating and pushing
vector<int> v;
v.reserve(N); // N is the expected size, but right now [0] is undefined.
for (...) {
v.push_back(...); // No problems in adding more than N elements, but may have to reallocate.
}
OPTION 2: Resizing and filling
vector<int> v;
v.resize(N);
for (size_t i=0;i<N;i++)
v[i] = ...; // You can't write past N-1 here!
OPTION 3: Create directly with the correct size, then fill
vector<int> v(N);
for (size_t i=0;i<N;i++)
v[i] = ...; // You can't write past N-1 here!
OPTION 4: Create a vector with the correct size and initialized to some fixed value
vector<int> v(N,val); // v[0:N-1] are all equal to val
Because when you first create a vector it is empty so vector[0] doesn't exist. push_back adds an element to the vector then you can modify or read it with vector[i]
Just to make everything 100% clear, your declaration of a vector,
vector<int> v;
is in some sense similar to the declaration of a variable:
int x;
and if you then want, say,
cout << x;
you will get rubbish. Though, if you declare
int x(2);
everything will be fine. Similarly for vectors: declaration of
vector<int> v;
allocates some memory space for a vector, but not fills it. You can then specify
vector<int> v(2);
which means that you now have declared a vector of two elements, or go for a vector-only feature - push_back. This would add elements to your vector, as you've noticed.
Because std::vector<int> isn't std::map<int, int>.
std::vector requires you to manually push_back() or (in C++11) emplace_back() elements for them to be included in the collection. And of course some of its constructors allows you to include initial elements to it. And of course again its assignment operators.
The subscript([]) operator should only be used in reading and/or modifying existing elements. Indexing using operator[] out-of-bounds (non-existent) elements would result in undefined behavior.
You can't access v[0] because there is no v[0] yet. The vector starts off default-constructed as an empty vector. You push an element onto the back and it grows in size by 1. You're then able to access the element you just added. If you want it to start off with one element, use the appropriate constructor:
std::vector<int> v(1); //one zeroed integer
You're comparing apples and oranges. int i = 0; would be like std::vector<int> v;.
You should first allocate memory for setting element values, such as
v.resize(new_size);
or use push_back method to add elements.

assigning vector

how I can assign v[i] to an series of integers ( type of v is vector ) without initially filling inside
Do you mean initializing std::vector to a series of integers?
int i[] = {1, 2, 3, 4, 5};
std::vector<int> myVector(i, i+ (sizeof(i)/sizeof(int)));
If you meant to create a vector of some elements so you can perform the assignment using their index values. Here, the following statement declares and initializes a vector with its elements being default initialized to 0.
std::vector<int> myVector(5); // constructs a vector of size five integers.
for (int x = 0; x < 5; x++)
myVector[x] = i[x]; // assign values using subscript [..]
But I think the even better way to go would be as #CashCow mentioned in his answer.
Also, note that you can also pre-allocate memory to add elements into the vector with avoiding any repeated memory allocations.
For example:
std::vector<int> myVector; // empty vector for integers
myVector.reserve(5); // pre-allocates memory for five integers
for (int i = 0; i < 5; i++) // now, you can add your elements
myVector.push_back(i);
It is usually a good idea to pre-allocate memory if you know the size of elements i.e in case of large number of elements when the performance is an important factor.
If you have anything that has the traits of an iterator you can use vector's assign method:
std::vector<int> v;
v.assign( iterStart, iterEnd );
iterStart should be such that *iterStart is the first value you want to add.
iterEnd should be one past the end, it is a terminating condition
++iter would move you to the next iterator in the input series.
I don't know what you mean by assign v[i] though. You cannot assign an element to a series. If you want to write the series at a location into an existing vector you can use insert instead of assign.
common way of adding items is calling std::vector<>push_back() method.
std::vector<int> myVector;
myVector.push_back(5);
myVector.push_back(10);
myVector.push_back(3);