tags:

views:

141

answers:

3

Hi,

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!

+3  A: 
andand
additionally, if this operation makes sense for your particular domain and you use it everywhere, overload operator+ and do what andand says inside of the definition.
Dave
This does not reverse the order of the inputs. Also dislike use of [] instead of iterators.
Steve Townsend
@Steve Townsend: The OP didn't want to reverse the order of the inputs. As for [] vs iterators, I grew up on Fortran, Pascal and C and find iterators to be excessively verbose for simple things like this... but I've updated for those interested in such things.
andand
@andand - OP's question stated "I would like to add both vectors starting at the last element and working backwards". Use of iterators may be verbose but it's more efficient and expressive than []. We get pointer addition (or subtraction, since we are moving back) rather than multiplication to access via index.
Steve Townsend
+4  A: 

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;
    }
}
Seth Johnson
+2  A: 

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.

no one important