How to Add Element by Element of Two Stl Vectors

How to add element by element of two STL vectors?

If you are trying to append one vector to another, you can use something like the following. These are from one of my utilities libraries--two operator+= overloads for std::vector: one appends a single element to the vector, the other appends an entire vector:

template <typename T>
std::vector<T>& operator+=(std::vector<T>& a, const std::vector<T>& b)
{
a.insert(a.end(), b.begin(), b.end());
return a;
}

template <typename T>
std::vector<T>& operator+=(std::vector<T>& aVector, const T& aObject)
{
aVector.push_back(aObject);
return aVector;
}

If you are trying to perform a summation (that is, create a new vector containing the sums of the elements of two other vectors), you can use something like the following:

#include <algorithm>
#include <functional>

template <typename T>
std::vector<T> operator+(const std::vector<T>& a, const std::vector<T>& b)
{
assert(a.size() == b.size());

std::vector<T> result;
result.reserve(a.size());

std::transform(a.begin(), a.end(), b.begin(),
std::back_inserter(result), std::plus<T>());
return result;
}

You could similarly implement an operator+= overload.

Sum two vector and store stl algorithm

You can use std:::transform

std::transform(v1.begin(), v1.end(), v2.begin(), v2.begin(), std::plus<>());

Sum values of 2 vectors

You can use std::transform and std::plus<int>()

std::vector<int> a;//looks like this: 2,0,1,5,0
std::vector<int> b;//looks like this: 0,0,1,3,5

// std::plus adds together its two arguments:
std::transform (a.begin(), a.end(), b.begin(), a.begin(), std::plus<int>());
// a = 2,0,2,8,5

This form of std::transform takes 5 arguments:

  • Two first are input iterators to the initial and final positions of the first sequence.
  • The third is an input iterator to the initial position of the second range.
  • The fourth is an output iterator of the initial position of the range where the operation results are stored.
  • The last argument is a binary function that accepts two elements as argument (one of each of the two sequences), and returns some result value convertible to the type pointed by OutputIterator.

How to sum up elements of a C++ vector?

Actually there are quite a few methods.

int sum_of_elems = 0;

C++03

  1. Classic for loop:

     for(std::vector<int>::iterator it = vector.begin(); it != vector.end(); ++it)
    sum_of_elems += *it;
  2. Using a standard algorithm:

     #include <numeric>

    sum_of_elems = std::accumulate(vector.begin(), vector.end(), 0);

    Important Note: The last argument's type is used not just for the initial value, but for the type of the result as well. If you put an int there, it will accumulate ints even if the vector has float. If you are summing floating-point numbers, change 0 to 0.0 or 0.0f (thanks to nneonneo). See also the C++11 solution below.

C++11 and higher


  1. b. Automatically keeping track of the vector type even in case of future changes:

     #include <numeric>

    sum_of_elems = std::accumulate(vector.begin(), vector.end(),
    decltype(vector)::value_type(0));
  2. Using std::for_each:

     std::for_each(vector.begin(), vector.end(), [&] (int n) {
    sum_of_elems += n;
    });
  3. Using a range-based for loop (thanks to Roger Pate):

     for (auto& n : vector)
    sum_of_elems += n;

C++17 and above


  1. Using std::reduce which also takes care of the result type, e.g if you have std::vector<int>, you get int as result. If you have std::vector<float>, you get float. Or if you have std::vector<std::string>, you get std::string (all strings concatenated). Interesting, isn't it?

    auto result = std::reduce(v.begin(), v.end());

    There are other overloads of this function which you can run even parallelly, in case if you have a large collection and you want to get the result quickly.

Adding values of two separate int vectors with different sizes?

Here's a simple approach I devised on the conditions required: (considering vectors v1 and v2, of data type DT)

  • Size difference: For cases where the vectors are of unequal sizes, you can simply append 0 at the end by using std::vector<>::insert(iterator, 0) with the iterator set to the beginning, since you'll need the zeroes to come first for proper element-to-element addition. Prior to that though, check which of the two vectors is larger in size, then collect the difference and insert for the same amount of times in a loop:
   int diff;
if(v1.size() > v2.size())
{ diff = v1.size() - v2.size();
for(int i = 0; i < diff; ++i)
v2.insert(v2.begin(), 0);
}
else
{ diff = v2.size() - v1.size();
for(int i = 0; i < diff; ++i)
v1.insert(v1.begin(), 0);
}
  • Addition: Now that the vectors are of equal sizes, you can use std::plus from the functional header for adding elements of one vector (say v1) to the other vector (v2) element-wise, emplaced with proper iterator positions in a std::transform:
std::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(), std::plus<DT>());

This will collect the element-wise sum of v1 and v2 into v1 (interchangeable). The only remaining issue or condition to deal with is the overflow for cases when element-wise additions sum up to be greater than or equal to 10.

  • Overflow: For all the elements in the vector apart from the first one (at 0th index), we will need to carry/add 1 to the next element in cases of overflow (>=10) and assign the current vector element to its remainder when divided by 10. However, for the first element to overflow, we'll need to assign another element to the vector's beginning (eg: {3, 1} + {9, 2} = {1, 2, 3}) , which will be a 1 again (considering single digit vector elements), for which we can impose seperate if statements:
   for(int i = v1.size(); i > 0; --i) 
{
if(i == 1 && v1[1] >= 10)
{ v1[1] %= 10;
v1.insert(v1.begin(), 1);
}
else if(i != 1 && v1[i-1] >= 10)
{ v1[i - 1] %= 10;
v1[i - 2] += 1;
}
}

Examples:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#define DT long long int
int main()
{
std::vector<DT> v1 = {5, 2, 5, 7, 8};
std::vector<DT> v2 = {4, 5, 6};

// 52578
// 00456
// -----
// Expected output: // 53034

// Size management:
int diff;
if(v1.size() > v2.size())
{ diff = v1.size() - v2.size();
for(int i = 0; i < diff; ++i)
v2.insert(v2.begin(), 0);
}
else
{ diff = v2.size() - v1.size();
for(int i = 0; i < diff; ++i)
v1.insert(v1.begin(), 0);
}

// Element-wise addition:
std::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(),std::plus<DT>());

// Overflow management:
for(int i = v1.size(); i > 0; --i)
{
if(i == 1 && v1[1] >= 10)
{ v1[1] %= 10;
v1.insert(v1.begin(), 1);
}
else if(i != 1 && v1[i - 1] >= 10)
{ v1[i - 1] %= 10;
v1[i - 2] += 1;
}
}

// Display the sum:
for(auto v:v1)
std::cout << v;
}

Output: 53034.

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#define DT long long int
int main()
{
std::vector<DT> v1 = {5, 2, 5, 7};
std::vector<DT> v2 = {9, 3, 7, 2};

// 5257
// 9372
// -----
// Expected output: // 14629

// Size management:
int diff;
if(v1.size() > v2.size())
{ diff = v1.size() - v2.size();
for(int i = 0; i < diff; ++i)
v2.insert(v2.begin(), 0);
}
else
{ diff = v2.size() - v1.size();
for(int i = 0; i < diff; ++i)
v1.insert(v1.begin(), 0);
}

// Element-wise addition:
std::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(),std::plus<DT>());

// Overflow management:
for(int i = v1.size(); i > 0; --i)
{
if(i == 1 && v1[1] >= 10)
{ v1[1] %= 10;
v1.insert(v1.begin(), 1);
}
else if(i != 1 && v1[i-1] >= 10)
{ v1[i - 1] %= 10;
v1[i - 2] += 1;
}
}

// Display the sum:
for(auto v:v1)
std::cout << v;
}

Output: 14629.

Inserting elements into 2D vector

To push on the vector that is an element of another vector, you simply do this

adjList[x].push_back();

Moving elements from std::vector to another one

The std::move lets you move the objects, as opposed to copying them, allowing for a potentially faster execution speed. The savings may be even greater when you move a range of values. However, when you do move a range from a container, the container still holds the places that were once occupied by these values.

You need to resize the container manually to remove these placeholders if you want to get rid of them (you don't have to, in case you would prefer reusing these container spots for other elements). One way to do it is to call vector::erase on the same range that you moved out of the container.

How to change a particular element of a C++ STL vector

at and operator[] both return a reference to the indexed element, so you can simply use:

l.at(4) = -1;

or

l[4] = -1;


Related Topics



Leave a reply



Submit