Reputation: 1281
I have a number of vector containers of varying size each containing doubles. I would like to add the elements of each vector to create a single vector of doubles. This simple example will example what I'm talking about:
Consider two vectors A with three elements 3.0 2.0 1.0 and B with two elements 2.0 1.0. I would like to add both vectors starting at the last element and working backwards. This would give an array C with entries 3.0 4.0 2.0.
What would be the most elegant/efficent way of doing this?
Thanks!
Upvotes: 3
Views: 1298
Reputation: 17497
Copy the larger vector into C and then add (+=) the elements of the smaller against the associated elements of C.
Somthing like:
std::vector<double> add(const std::vector<double>& a,
const std::vector<double>& b)
{
std::vector<double> c( (a.size() > b.size()) ? a : b );
const std::vector<double>& aux = (a.size() > b.size() ? b : a);
size_t diff = c.size() - aux.size();
for (size_t i = diff; i < c.size(); ++i)
c[i] += aux[i-diff];
return c;
}
Edit Based on comment below objecting to use of [] vs iterators.
Personally I find iterators to be excessively verbose for something like this, but if you prefer them, then you could try somehting like the following:
std::vector<double> add(const std::vector<double>& a,
const std::vector<double>& b)
{
std::vector<double> c( (a.size() > b.size()) ? a : b);
std::vector<double>::reverse_iterator c_i;
const std::vector<double>& aux = (a.size() > b.size()) ? b : a;
std::vector<double>::const_reverse_iterator aux_i;
for (c_i=c.rbegin(), aux_i=aux.rbegin(); aux_i!=aux.rend(); ++c_i, ++aux_i)
*c_i += *aux_i;
return c;
}
I didn't test or compile either of these, but I think you get the idea.
Upvotes: 3
Reputation: 94
Once you know you have one vector that is larger than the other
std::vector<double> new_vector = bigger_vector; // Copy the largest
std::transform(smaller_vector.rbegin(), smaller_vector.rend(), // iterate over the complete smaller vector
bigger_vector.rbegin(), // 2nd input is the corresponding entries of the larger vector
new_vector.rbegin(), // Output is the new vector
std::plus<double>()); // Add em
This is nice because you don't have to do any loop indentation, and works on any sequence container that supports reverse iterators.
Upvotes: 4
Reputation: 15192
Try this with iterators:
#include <vector>
void add(
std::vector<double>& result,
const std::vector<double>& a,
const std::vector<double>& b)
{
std::vector<double>::const_reverse_iterator sit;
std::vector<double>::const_reverse_iterator send;
// copy the larger vector
if (a.size() > b.size() ) {
result = a;
sit = b.rbegin();
send = b.rend();
}
else {
result = b;
sit = a.rbegin();
send = a.rend();
}
// add the smaller one, starting from the back
for (std::vector<double>::reverse_iterator it = result.rbegin();
sit != send;
++it, ++sit)
{
*it += *sit;
}
}
Upvotes: 4