getting certain component of all elements in vector - c++

I have stored some elements of a struct, let's call it myStruct, in a vector.
Now I want to get a certain component of this struct of all the elements in my vector.
Is there a possibility to do this fast, without using a for-loop? Is there an equivalent solution for deque?
struct myStruct{
int a;
int b;
};
vector<myStruct> vec;
//creating some data and push back to vector
myStruct ms0,ms1;
ms0.a = 5;
ms1.a = 10;
vec.push_back(ms0);
vec.push_back(ms1);
//now I want to get the component a of ms0 and ms1

You could use two vectors, one storing component a, one storing component b, instead of one vector storing pairs (a, b).
If this doesn't work for you, you can do something like (this is C++11 or higher):
std::for_each(vec.begin(), vec.end(),
[] (myStruct &v) {std::cout << v.a << '\n';} );
But this is not (in terms of complexity) better than a for loop.

Vectors are sequence containers, more specifically arrays that can change their size dynamically, thus to access all of their elements it will take time proportional to their size, n. Thus the answer to your first question:
Is there a possibility to do this fast, without using a for-loop?
is: No
As for the second question:
Is there an equivalent solution for deque?
Yes, there is and it will look the same as the one posted, with the small difference in the container which instead of vector<myStruct> vec; will be std::deque<int> mydeque;

Internally vector uses arrays so you can directly access its elements using [] operator,
eg:
cout<< vec[0].a << vec[1].a;

Related

iterate over std::vector of std::vector [duplicate]

I'm trying to pass a variable of type vector<vector<double> > to a function F(double ** mat, int m, int n). The F function comes from another lib so I have no option of changing it. Can someone give me some hints on this? Thanks.
vector<vector<double>> and double** are quite different types. But it is possible to feed this function with the help of another vector that stores some double pointers:
#include <vector>
void your_function(double** mat, int m, int n) {}
int main() {
std::vector<std::vector<double>> thing = ...;
std::vector<double*> ptrs;
for (auto& vec : thing) {
// ^ very important to avoid `vec` being
// a temporary copy of a `thing` element.
ptrs.push_back(vec.data());
}
your_function(ptrs.data(), thing.size(), thing[0].size());
}
One of the reasons this works is because std::vector guarantees that all the elements are stored consecutivly in memory.
If possible, consider changing the signature of your function. Usually, matrices are layed out linearly in memory. This means, accessing a matrix element can be done with some base pointer p of type double* for the top left coefficient and some computed linear index based on row and columns like p[row*row_step+col*col_step] where row_step and col_step are layout-dependent offsets. The standard library doesn't really offer any help with these sorts of data structures. But you could try using Boost's multi_array or GSL's multi_span to help with this.
The way I see it, you need to convert your vector<vector<double> > to the correct data type, copying all the values into a nested array in the process
A vector is organised in a completely different way than an array, so even if you could force the data types to match, it still wouldn't work.
Unfortunately, my C++ experience lies a couple of years back, so I can't give you a concrete example here.
Vector< Vector< double> > is not nearly the same as a double pointer to m. From the looks of it, m is assumed to be a 2-dimensional array while the vector is could be stored jagged and is not necessarily adjacent in memory. If you want to pass it in, you need to copy the vector values into a temp 2dim double array as pass that value in instead.

Resizing std::vector without destroying elements

I am using all the time the same std::vector<int> in order to try to avoid allocating an deallocating all the time. In a few lines, my code is as follows:
std::vector<int> myVector;
myVector.reserve(4);
for (int i = 0; i < 100; ++i) {
fillVector(myVector);
//use of myVector
//....
myVector.resize(0);
}
In each for iteration, myVector will be filled with up to 4 elements. In order to make efficient code, I want to use always myVector. However, in myVector.resize() the elements in myVector are being destroyed. I understand that myVector.clear() will have the same effect.
I think if I could just overwrite the existing elements in myVector I could save some time. However I think the std::vector is not capable of doing this.
Is there any way of doing this? Does it make sense to create a home-grown implementation which overwrites elements ?
Your code is already valid (myVector.clear() has better style than myVector.resize(0) though).
'int destructor' does nothing.
So resize(0) just sets the size to 0, capacity is untouched.
Simply don't keep resizing myVector. Instead, initialise it with 4 elements (with std::vector<int> myVector(4)) and just assign to the elements instead (e.g. myVector[0] = 5).
However, if it's always going to be fixed size, then you might prefer to use a std::array<int, 4>.
Resizing a vector to 0 will not reduce its capacity and, since your element type is int, there are no destructors to run:
#include <iostream>
#include <vector>
int main() {
std::vector<int> v{1,2,3};
std::cout << v.capacity() << ' ';
v.resize(0);
std::cout << v.capacity() << '\n';
}
// Output: 3 3
Therefore, your code already performs mostly optimally; the only further optimisation you could make would be to avoid the resize entirely, thereby losing the internal "set size to 0" inside std::vector that likely comes down to an if statement and a data member value change.
std::vector is not a solution in this case. You don't want to resize/clear/(de)allocate all over again? Don't.
fillVector() fills 'vector' with number of elements known in each iteration.
Vector is internally represented as continuous block of memory of type T*.
You don't want to (de)allocate memory each time.
Ok. Use simple struct:
struct upTo4ElemVectorOfInts
{
int data[4];
size_t elems_num;
};
And modify fillVector() to save additional info:
void fillVector(upTo4ElemVectorOfInts& vec)
{
//fill vec.data with values
vec.elems_num = filled_num; //save how many values was filled in this iteration
}
Use it in the very same way:
upTo4ElemVectorOfInts myVector;
for (int i = 0; i < 100; ++i)
{
fillVector(myVector);
//use of myVector:
//- myVector.data contains data (it's equivalent of std::vector<>::data())
//- myVector.elems_num will tell you how many numbers you should care about
//nothing needs to be resized/cleared
}
Additional Note:
If you want more general solution (to operate on any type or size), you can, of course, use templates:
template <class T, size_t Size>
struct upToSizeElemVectorOfTs
{
T data[Size];
size_t elems_num;
};
and adjust fillVector() to accept template instead of known type.
This solution is probably the fastest one. You can think: "Hey, and if I want to fill up to 100 elements? 1000? 10000? What then? 10000-elem array will consume a lot of storage!".
It would consume anyway. Vector is resizing itself automatically and this reallocs are out of your control and thus can be very inefficient. If your array is reasonably small and you can predict max required size, always use fixed-size storage created on local stack. It's faster, more efficient and simpler. Of course this won't work for arrays of 1.000.000 elements (you would get Stack Overflow in this case).
In fact what you have at present is
for (int i = 0; i < 100; ++i) {
myVector.reserve(4);
//use of myVector
//....
myVector.resize(0);
}
I do not see any sense in that code.
Of course it would be better to use myVector.clear() instead of myVector.resize(0);
If you always overwrite exactly 4 elements of the vector inside the loop then you could use
std::vector<int> myVector( 4 );
instead of
std::vector<int> myVector;
myVector.reserve(4);
provided that function fillVector(myVector); uses the subscript operator to access these 4 elements of the vector instead of member function push_back
Otherwise use clear as it was early suggested.

Making only the outer vector in vector<vector<int>> fixed

I want to create a vector<vector<int>> where the outer vector is fixed (always containing the same vectors), but the inner vectors can be changed. For example:
int n = 2; //decided at runtime
assert(n>0);
vector<vector<int>> outer(n); //outer vector contains n empty vectors
outer.push_back(vector<int>()); //modifying outer vector - this should be error
auto outer_it = outer.begin();
(*outer_it).push_back(3); //modifying inner vector. should work (which it does).
I tried doing simply const vector<vector<int>>, but that makes even the inner vectors const.
Is my only option to create my own custom FixedVectors class, or are there better ways out there to do this?
by definition,
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.
if you aren't looking to have a data structure that changes in size, a vector probably isn't the best choice for an outer layer, How about using an array of vectors. This way the array is of a fixed size and cannot be modified, while still having the freedom of having its size declared in runtime.
vector<int> *outer;
int VectSize;
cout >> "size of vector array?"
cin >> VectSize;
outer = new vector<int>[VectSize]; //array created with fixed size
outer.push_back() //not happening
Wrap the outer vector into a class which just provides at, begin, end and operator []. Let the class take only have one constructor taking its capacity.
This most probably the best way.
const vector<unique_ptr<vector<int>>> outer = something(n);
For the something, you might write a function, like this:
vector<unique_ptr<vector<int>>> something(int n)
{
vector<unique_ptr<vector<int>>> v(n);
for (auto & p : v)
p.reset(new vector<int>);
return v;
}

Adding element to Array of Objects in C++

How do I add an element to the end of an array dynamically in C++?
I'm accustomed to using vectors to dynamically add an element. However, vectors does not seem to want to handle an array of objects.
So, my main goal is having an array of objects and then being able to add an element to the end of the array to take another object.
EDIT**
Sorry, its the pushback() that causes me the problems.
class classex
{
private:
int i;
public:
classex() { }
void exmethod()
{
cin >> i;
}
};
void main()
{
vector <classex> vectorarray;
cout << vectorarray.size();
cout << vectorarray.push_back();
}
Now I know push_back must have an argument, but What argument?
Now I know push_back must have an argument, but What argument?
The argument is the thing that you want to append to the vector. What could be simpler or more expected?
BTW, you really, really, really do not want exmethod as an actual method of classex in 99% of cases. That's not how classes work. Gathering the information to create an instance is not part of the class's job. The class just creates the instance from that information.
Arrays are fixed sized containers. So enlarging them is not possible. You work around this and copy one array in a bigger and gain space behind the old end, but that's it.
You can create a array larger than you currently need it and remember which elements are empty. Of course they are never empty (they at least contain 0's), but that's a different story.
Like arrays, there are many containers, some are able to grow, like the stl containers: lists, vectors, deques, sets and so on.
add a Constructor to set i (just to give your example a real world touch) to your example classex, like this:
class classex {
public:
classex(int& v) : i(v) {}
private:
int i;
};
An example for a growing container looks like this:
vector <classex> c; // c for container
// c is empty now. c.size() == 0
c.push_back(classex(1));
c.push_back(classex(2));
c.push_back(classex(3));
// c.size() == 3
EDIT: The question was how to add an element to an array dynamically allocated, but the OP actually mean std::vector. Below the separator is my original answer.
std::vector<int> v;
v.push_back( 5 ); // 5 is added to the back of v.
You could always use C's realloc and free. EDIT: (Assuming your objects are PODs.)
When compared to the requirement of manually allocating, copying, and reallocating using new and delete, it's a wonder Stroustrup didn't add a keyword like renew.

How to have a vector of byvalue and use a vector of pointers in conjunction?

I have some vectors of class A objects:
std::vector<A> *V1;
std::vector<A> *V2;
etc
there is a function with a vector of pointers of A:
std::vector<A *> *arranged;
what I need to do is put the vectors from V1, V2 etc inside arranged without destroying them in the end, so I thought that a vector of pointers to those objects... is this possible?
if yes, can you give me an example of a iteration with variable V1 and add pointers of those objects into arranged?
imagine that you, temporarly, need to sort 3 vectors of objects into one vector but you don't want to mess up the memory of the 3 vectors.
ty,
Joe
You could write your own comparator. In this case, the comparator would work on A*. A simple example using int type:
void fun(vector<int*>* vec)
{
/////////
}
bool comp(int* lhs, int* rhs)
{
return *lhs < *rhs;
}
int main()
{
vector<int> first, second;
vector<int*> vec;
for(vector<int>::size_type i = 0; i < first.size(); ++i)
vec.push_back(&first[i]);
for(vector<int>::size_type i = 0; i < second.size(); ++i)
vec.push_back(&second[i]);
// write your own comparator! provided above: comp
sort(vec.begin(), vec.end(), comp);
fun(&vec);
return 0;
}
If I understand you correctly - you've several vectors containing some object type (A), and you want to create a new vector containing the composition of all members of the other vectors w/o actually copying the objects around, or otherwise disturbing their owning-vectors in any way?
First: does the new composite vector's life definitely exist such that none of its source-vectors will change? That is: you cannot just have raw pointers into the source-vectors from your composite vector if those pointers will be invalidated within the lifetime of your composite.
If the answer to that is anything other than "definitely, pointers will remain valid" then you need to consider using shared pointers, or something similar, such that altering the source-vectors will not leave your composite vector in an invalid state (i.e. not leave it pointing to random memory).
Assuming that the source-vectors will remain unchanged in terms of their own contents for the life span of your composite, then the simple answer is "Yes"
vector<A> source1;
vector<A> source2;
vector<A> source3;
vector<const A*> composite; // this is a sorted vector of the above vectors' contents (by pointer)
For the composite vector, you would need to put the contents (by copy) of source1-3 into it, and then sort it (or you could use a sorted container, and sort as you insert the elements). You'll need to define your own sorting operator, one that dereferences the pointers and applies whatever sort-algorithm on the target objects themselves.
Does that help you?