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 vector
s), 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
Classic for loop:
for(std::vector<int>::iterator it = vector.begin(); it != vector.end(); ++it)
sum_of_elems += *it;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
to0.0
or0.0f
(thanks to nneonneo). See also the C++11 solution below.
C++11 and higher
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));Using
std::for_each
:std::for_each(vector.begin(), vector.end(), [&] (int n) {
sum_of_elems += n;
});Using a range-based for loop (thanks to Roger Pate):
for (auto& n : vector)
sum_of_elems += n;
C++17 and above
Using
std::reduce
which also takes care of the result type, e.g if you havestd::vector<int>
, you getint
as result. If you havestd::vector<float>
, you getfloat
. Or if you havestd::vector<std::string>
, you getstd::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 usingstd::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 thefunctional
header for adding elements of one vector (sayv1
) to the other vector (v2
) element-wise, emplaced with proper iterator positions in astd::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 a1
again (considering single digit vector elements), for which we can impose seperateif
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
How to Add the Mingw Bin Directory to My System Path
What's the Point in Defaulting Functions in C++11
Iteration Through Std Containers in Openmp
How to Find Longest Common Substring Using C++
How to Speed Up Matrix Multiplication in C++
How to Use the _Attribute_((Visibility("Default")))
What's Time Complexity of This Algorithm for Finding All Combinations
C++11 Type Trait to Differentiate Between Enum Class and Regular Enum
Manual for Cross-Compiling a C++ Application from Linux to Windows
Is There Any Advantage to Using Pow(X,2) Instead of X*X, with X Double
How to Access MySQL from Multiple Threads Concurrently
Can Using a Lambda in Header Files Violate the Odr
What Would a Std::Map Extended Initializer List Look Like
How to Store Array in One Column in SQLite3