Can I get rid of nested for loops here? - c++

I have a function that takes a vector and returns a vector by combining all the elements in it. Right now, I have 3 nested for loops that create a combination that is 3 levels deep. I would like it to look better and have the ability to add the functionality to make it 4 levels deep when I want.
If input = ["one", "two", "three"]
3 level output = "onetwothree" "twoonethree" and so on.
std::vector<std::string> generator(std::vector<std::string>& x)
{
std::vector<std::string> output;
std::string tmp;
for (auto i : x) {
output.push_back(i);
for (auto j : x) {
tmp = i + j;
output.push_back(tmp);
for (auto k : x) {
tmp = i + j + k;
output.push_back(tmp);
}
}
}
return output;
}
I have looked into iterators, but I can't figure out if it would work.

If what you are looking for is to simply generate the permutations of all the elements of the string vector x and store these permutations into another output vector, this is easily accomplished by using std::next_permutation and std::accumulate:
#include <vector>
#include <string>
#include <numeric>
#include <iostream>
#include <algorithm>
std::vector<std::string> generator(std::vector<std::string> x)
{
std::vector<std::string> output;
std::sort(x.begin(), x.end());
do
{
output.push_back(std::accumulate(x.begin(), x.end(), std::string()));
} while (std::next_permutation(x.begin(), x.end()));
return output;
}
int main()
{
auto v = generator({"one","two","three"});
for (auto& val : v)
std::cout << val << "\n";
}
Live Example
The std::accumulate basically calls operator + on the elements by default, thus the string is automatically concatenated.
As far as std::next_permutation, the description of what it does is explained at the link. Basically you want to start out with a sorted sequence, and call std::next_permutation to get the next permutation of elements.
Note that this is not contingent of the number of "levels" (as you call it). You could have a vector of 10 strings, and this would work correctly (assuming there are no memory constraints).

If you want to generate all combinations of N words with max length L you could use this:
std::vector<std::string> generator(const std::vector<std::string> & x, int levels) {
int nWords = x.size();
std::vector<std::string> output;
for (int l = 1; l <= levels; ++l) {
int nCombs = std::pow(nWords, l);
for (int i = 0; i < nCombs; ++i) {
std::string cur;
for (int j = 0, k = i; j < l; ++j) {
cur += x[k%nWords];
k /= nWords;
}
output.push_back(cur);
}
}
return output;
}
Live Example
There are still 3 nested loops, but this works for any value of L - not just 3. L > N also works.

Hi I had the similar problem in Python once.
The goal I suppose is to have a "n-nested" loops such that n is a variable. A better result would be to make each index I_i of level i be variables. That is to say, given a list [I_1,I_2,...,I_n], you should be able to generate such loop
for i_1 in range( I_1):
for i_2 in range( I_2):
...
for i_n in range(I_n):
some_function(i_1,i_2,...,i_n)
One way to do this is to use mathematics. You can build a number such that on the ith digit, it's I_i based. This number's maxmium value is just I_1*I_2*...*I_n. In this way, the entire loop will be collaped into one simple loop
for i in range(I_1*I_2*...*I_n):
# obtain these numbers
i_1 = f_1(i)
i_2 = f_2(i)
...
i_n = f_n(i)
some_function(i_1,i_2,...,i_n)
Although the functions to obtain the is are a bit complicated.
Another way to do it is, as you have mentioned, iterators. In Python it's just import itertools. In C++, however, I found this cppitertools. I haven't tried it, but I suppose this could work.
Still, if you want speed, the first approch is preferred. Still, I think there are better solutions.

Related

how to avoid this for-loop mess in c++?

I need to program all possible sets of numbers from 1 to N for an arbitrary number m of integers without permutation.
Since I don't know how to explain it better here are some examples:
for m = 2
vector<vector<int>> box;
int N = 5;
for(int i = 1; i <= N; i++) {
for(int j = N; j >= i; j--) {
vector<int> dummy;
dummy.push_back(i);
dummy.push_back(j);
box.push_back(dummy);
}
}
for m = 3
vector<vector<int>> box;
int N = 5;
for(int i = 1; i <= N; i++) {
for(int j = N; j >= i; j--) {
for(int k = N; k >= j; k--) {
vector<int> dummy;
dummy.push_back(i);
dummy.push_back(j);
dummy.push_back(k);
box.push_back(dummy);
}
}
}
This works perfectly fine and the result is what I need. But like already mentioned, m can be arbitrary and I can't be bothered to implement this for m = 37 or what ever. N and m are known values but change while the program is running. There must be a better way to implement this than for the m = 37 case to implement a row of 37-for-loops. Can someone help me? I'm kind a clueless :\
edit: to explain better what I'm looking for here are some more examples.
Let's say N = 5 and m = 4, than 1223 is a feasible solution for me, 124 is not since it is to short. Let's say I already found 1223 as a solution, than I don't need 2123, 2213 or any other permutation of this number.
edit2: Or if you prefer a more visual (mathematical?) problem formulation here you go.
Consider m the dimension. With m been 2 you are left with a N size Matrix. I am looking for the upper (or lower) triangle of this Matrix including the diagonal. Let's move to m = 3, the Matrix becomes a 3 dimensional cube (or Tensor if you so wish), now I'm looking for the upper (or lower) tetrahedron including the diagonal-plain. For higher dimensions than 3 I'm looking for the hyper-tetrahedron of the hyper-cube including the hyper-diagonal-plane.
http://howardhinnant.github.io/combinations.html
The following generic algorithms permit a client to visit every combination or permuation of a sequence of length N, r items at time.
Example usage:
std::vector<std::vector<int>> box;
std::vector<int> v(N);
std::iota(begin(v), end(v), 1);
for_each_combination(begin(v), begin(v) + M, end(v), [](auto b, auto e) {
box.emplace_back(b, e);
return false;
});
The above code just shows inserting each combination into box as an example, but you probably don't want to actually do that: assuming that box is simply an intermediary and that your actual work then uses it somewhere else, you can avoid an intermediary and simply do whatever work you need directly in the body of the functor.
Here's a complete, working example using code from the provided link.
Since what you want is combinations with repetition rather than just combinations. Here's an example of implementing this on top of for_each_combination():
template<typename Func>
void for_each_combination_with_repetition(int categories, int slots, Func func) {
std::vector<int> v(slots + categories - 1);
std::iota(begin(v), end(v), 1);
std::vector<int> indices;
for_each_combination(begin(v), begin(v) + slots, end(v), [&](auto b, auto e) {
indices.clear();
int last = 0;
int current_element = 0;
for(;b != e; ++last) {
if (*b == last+1) {
indices.push_back(current_element);
++b;
} else {
++current_element;
}
}
func(begin(indices), end(indices));
return false;
});
}
The wikipedia article on combinations shows a good illustration of what this is doing: it's getting all the combinations (without repetition) of numbers [0, N + M - 1) and then looking for the 'gaps' in the results. The gaps represent transitions from repetitions of one element to repetitions of the next.
The functor you pass to this algorithm is given a range that contains indices into a collection containing the elements you're combining. For example if you want to get all sets of three elements from the set of {x,y}, the results are you want are {{x,x,x}, {x,x,y}, {x,y,y}, {y,y,y}}, and this algorithm represents this by returning ranges of indices into the (ordered) set {x,y}: {{0,0,0}, {0,0,1}, {0,1,1}, {1,1,1}}.
So normally to use this you have a vector or something containing your elements and use the ranges produced by this algorithm as indices into that container. However in your case, since the elements are just the numbers from 1 to N you can use the indices directly by adding one to each index:
for_each_combination_with_repetition(N, M, [&](auto b, auto e) {
for(; b != e; ++b) {
int index = *b;
std::cout << index + 1 << " ";
}
std::cout << '\n';
});
Complete example
An alternative implementation can return vectors that represent counts of each category. E.g. the earlier {{x,x,x}, {x,x,y}, {x,y,y}, {y,y,y}} results could be represented by: {{3,0} {2,1},{1,2}, {0,3}}. Modifying the implementation to produce this representation instead looks like this:
template<typename Func>
void for_each_combination_with_repetition(int categories, int slots, Func func) {
std::vector<int> v(slots + categories - 1);
std::iota(begin(v), end(v), 1);
std::vector<int> repetitions(categories);
for_each_combination(begin(v), begin(v) + slots, end(v), [&](auto b, auto e) {
std::fill(begin(repetitions), end(repetitions), 0);
int last = 0;
int current_element = 0;
for(;b != e; ++last) {
if (*b == last+1) {
++repetitions[current_element];
++b;
} else {
++current_element;
}
}
func(begin(repetitions), end(repetitions));
return false;
});
}
You can use recursion to find all subsets. This can probably be improved stylistically, but here is a quick take at the problem:
std::vector<std::set<int>> subsets(std::vector<int> x)
{
if (x.size() == 0)
return { std::set<int>() };
else
{
int last = x.back();
x.pop_back();
auto sets = subsets(x);
size_t n = sets.size();
for (size_t i = 0; i < n; i++)
{
std::set<int> s = sets[i];
s.insert(last);
sets.push_back(std::move(s));
}
return sets;
}
}
This doubles the number of answers at each recursion step : the number of subsets is 2^n, as expected.
You can substitute std::set for std::vector if you wish.

Find number of occurrences of numbers in a vector in C++

I have a vector of integers. which contains numbers. I want to count the number of occurrences of every number in this vector. So what will be the optimum way to do this. As I am new to Vectors please let me know any optimum method.
You can use a hash table, implemented by std::unordered_map. For example:
#include <unordered_map>
#include <vector>
void count_occurrence(std::unordered_map<int,int>& m, std::vector<int>& v){
for (auto itr = v.begin(); itr != v.end(); ++itr){
++m[*itr];
}
}
//...somewhere else
//you already have std::vector v filled
std::unordered_map<int,int> m;
count_occurrence(m, v);
//print the number of occurrences of 1
std::cout<<m[1]<<std::endl;
You could sort the elements of the vector
Iterate through vector
Store the current integer as x
Compare current index to previous index.
If they are equal, increment another variable as f
If they are unequal, begin the cycle again
This of course is by no means a step by step instruction, but it contains enough direction to get you going
To find the mode of a number of integers stored in an array/list/vector/etc. where v is the DS and num is the number of integers.
You may use the following technique:
Its simple and sober.
i = 0;
int m = 0, mode, c = 0, nc = 0;
while(i<num)
{
c = 0;
nc = v[i];
c++;
i++;
while(nc == v[i])
{
c++;
i++;
}
if(m < c)
{
m = c;
mode = nc;
}
}

remove duplicates int number in a vector c++

I'm trying to remove the same integer numbers in a vector. My aim is to have only one copy them. Well I wrote a simple code, but it doesn't work properly. Can anyone help? Thanks in advance.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int a = 10, b = 10 , c = 8, d = 8, e = 10 , f = 6;
vector<int> vec;
vec.push_back(a);
vec.push_back(b);
vec.push_back(c);
vec.push_back(d);
vec.push_back(e);
vec.push_back(f);
for (int i=vec.size()-1; i>=0; i--)
{
for(int j=vec.size()-1; j>=0; j--)
{
if(vec[j] == vec[i-1])
vec.erase(vec.begin() + j);
}
}
for(int i=0; i<vec.size(); i++)
{
cout<< "vec: "<< vec[i]<<endl;
}
return 0;
}
Don't use a list for this. Use a set:
#include <set>
...
set<int> vec;
This will ensure you will have no duplicates by not adding an element if it already exists.
To remove duplicates it's easier if you sort the array first. The code below uses two different methods for removing the duplicates: one using the built-in C++ algorithms and the other using a loop.
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;
int main() {
int a = 10, b = 10 , c = 8, d = 8, e = 10 , f = 6;
vector<int> vec;
vec.push_back(a);
vec.push_back(b);
vec.push_back(c);
vec.push_back(d);
vec.push_back(e);
vec.push_back(f);
// Sort the vector
std::sort(vec.begin(), vec.end());
// Remove duplicates (v1)
std::vector<int> result;
std::unique_copy(vec.begin(), vec.end(), std::back_inserter(result));
// Print results
std::cout << "Result v1: ";
std::copy(result.begin(), result.end(), std::ostream_iterator<int>(cout, " "));
std::cout << std::endl;
// Remove duplicates (v2)
std::vector<int> result2;
for (int i = 0; i < vec.size(); i++) {
if (i > 0 && vec[i] == vec[i - 1])
continue;
result2.push_back(vec[i]);
}
// Print results (v2)
std::cout << "Result v2: ";
std::copy(result2.begin(), result2.end(), std::ostream_iterator<int>(cout, " "));
std::cout << std::endl;
return 0;
}
If you need to save initial order of numbers you can make a function that will remove duplicates using helper set<int> structure:
void removeDuplicates( vector<int>& v )
{
set<int> s;
vector<int> res;
for( int i = 0; i < v.size(); i++ ) {
int x = v[i];
if( s.find(x) == s.end() ) {
s.insert(x);
res.push_back(x);
}
}
swap(v, res);
}
The problem with your code is here:
for(int j=vec.size()-1; j>=0; j--)
{
if(vec[j] == vec[i-1])
vec.erase(vec.begin() + j);
}
there's going to be a time when j==i-1 and that's going to kill your algorithms and there will be a time when i-1 < 0 so you will get an out of boundary exception.
What you can do is to change your for loop conditions:
for (int i = vec.size() - 1; i>0; i--){
for(int j = i - 1; j >= 0; j--){
//do stuff
}
}
this way, your the two variables your comparing will never be the same and your indices will always be at least 0.
Others have already pointed to std::set. This is certainly simple and easy--but it can be fairly slow (quite a bit slower than std::vector, largely because (like a linked list) it consists of individually allocated nodes, linked together via pointers to form a balanced tree1.
You can (often) improve on that by using an std::unordered_set instead of a std::set. This uses a hash table2 instead of a tree to store the data, so it normally uses contiguous storage, and gives O(1) expected access time instead of the O(log N) expected for a tree.
An alternative that's often faster is to collect the data in the vector, then sort the data and use std::unique to eliminate duplicates. This tends to be best when you have two distinct phases of operation: first you collect all the data, then you need duplicates removed. If you frequently alternate between adding/deleting data, and needing a duplicate free set, then something like std::set or std::unordered_set that maintain the set without duplicates at all times may be more useful.
All of these also affect the order of the items. An std::set always maintains the items sorted in a defined order. With std::unique you need to explicit sort the data. With std::unordered_set you get the items sorted in an arbitrary order that's neither their original order nor is it sorted.
If you need to maintain the original order, but without duplicates, you normally end up needing to store the data twice. For example when you need to add a new item, you attempt to insert it into an std::unordered_set, then if and only if that succeeds, add it to the vector as well.
Technically, implementation as a tree isn't strictly required, but it's about the only possibility of which I'm aware that can meet the requirements, and all the implementations of which I'm aware are based on trees.
Again, other implementations might be theoretically possible, but all of which I'm aware use hashing--but in this case, enough of the implementation is exposed that avoiding a hash table would probably be even more difficult.
The body of a range for must not change the size of the sequence over which it is iterating..
you can remove duplicates before push_back
void push(std::vector<int> & arr, int n)
{
for(int i = 0; i != arr.size(); ++i)
{
if(arr[i] == n)
{
return;
}
}
arr.push_back(n);
}
... ...
push(vec, a);
push(vec, b);
push(vec, c);
...

Given a vector with integers from 0 to n, but not all included, how do I efficiently get the non-included integers?

Given a vector with integers from 0 to n, but not all included, how do I efficiently get the non-included integers?
For example if I have a vector with 1 2 3 5, I need to get the vector that contains 0 4.
But I need to do it very efficiently.
Since the vector is already sorted, this becomes trivial:
vector<int> v = {1,2,3,5};
vector<int> ret;
v.push_back(n+1); // this is to enforce a limit using less branches in the loop
for(int i = 0, j = 0; i <= n; ++i){
int present = v[j++];
while(i < present){
ret.push_back(i++);
}
}
return ret;
Additionally, if it wasn't sorted, you could either sort it and apply the above algorithm, or, if you know the range of n, and you can afford the extra memory, you could instead create an array of boolean (or a bitset) and mark the index corresponding to every element you encounter (e.g. bitset[v[j++]] = true;), subsequently iterating from 0 to n and inserting into your vector every element whose bitset position has not been marked.
Basically the idea presented here is that we know the number of missing items beforehand if we can assume sorted input without duplicate values.
Then it is possible to pre-allocate enough space to hold the missing values beforehand (no later dynamic allocation required). Then we can also exploit the possible shortcut when all missing values were found.
If the input vector is not sorted or contains duplicate values, a wrapper function can be used that establishes this precondition.
#include <iostream>
#include <set>
#include <vector>
inline std::vector<int> find_missing(std::vector<int> const & input) {
// assuming non-empty, sorted input, no duplicates
// number of items missing
int n_missing = input.back() - input.size() + 1;
// pre-allocate enough memory for missing values
std::vector<int> result(n_missing);
// iterate input vector with shortcut if all missing values were found
auto input_it = input.begin();
auto result_it = result.begin();
for (int i = 0; result_it != result.end() && input_it != input.end(); ++i) {
if (i < *input_it) (*result_it++) = i;
else ++input_it;
}
return result;
}
// use this if the input vector is not sorted/unique
inline std::vector<int> find_missing_unordered(std::vector<int> const & input) {
std::set<int> values(input.begin(), input.end());
return find_missing(std::vector<int>(values.begin(), values.end()));
}
int main() {
std::vector<int> input = {1,2,3,5,5,5,7};
std::vector<int> result = find_missing_unordered(input);
for (int i : result)
std::cout << i << " ";
std::cout << "\n";
}
The output is:
$ g++ test.cc -std=c++11 && ./a.out
0 4 6

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

What are the good ways of finding the sum of all the elements in a std::vector?
Suppose I have a vector std::vector<int> vector with a few elements in it. Now I want to find the sum of all the elements. What are the different ways for the same?
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 to 0.0 or 0.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 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.
The easiest way is to use std:accumulate of a vector<int> A:
#include <numeric>
cout << accumulate(A.begin(), A.end(), 0);
Prasoon has already offered up a host of different (and good) ways to do this, none of which need repeating here. I'd like to suggest an alternative approach for speed however.
If you're going to be doing this quite a bit, you may want to consider "sub-classing" your vector so that a sum of elements is maintained separately (not actually sub-classing vector which is iffy due to the lack of a virtual destructor - I'm talking more of a class that contains the sum and a vector within it, has-a rather than is-a, and provides the vector-like methods).
For an empty vector, the sum is set to zero. On every insertion to the vector, add the element being inserted to the sum. On every deletion, subtract it. Basically, anything that can change the underlying vector is intercepted to ensure the sum is kept consistent.
That way, you have a very efficient O(1) method for "calculating" the sum at any point in time (just return the sum currently calculated). Insertion and deletion will take slightly longer as you adjust the total and you should take this performance hit into consideration.
Vectors where the sum is needed more often than the vector is changed are the ones likely to benefit from this scheme, since the cost of calculating the sum is amortised over all accesses. Obviously, if you only need the sum every hour and the vector is changing three thousand times a second, it won't be suitable.
Something like this would suffice:
class UberVector:
private Vector<int> vec
private int sum
public UberVector():
vec = new Vector<int>()
sum = 0
public getSum():
return sum
public add (int val):
rc = vec.add (val)
if rc == OK:
sum = sum + val
return rc
public delindex (int idx):
val = 0
if idx >= 0 and idx < vec.size:
val = vec[idx]
rc = vec.delindex (idx)
if rc == OK:
sum = sum - val
return rc
Obviously, that's pseudo-code and you may want to have a little more functionality, but it shows the basic concept.
Why perform the summation forwards when you can do it backwards? Given:
std::vector<int> v; // vector to be summed
int sum_of_elements(0); // result of the summation
We can use subscripting, counting backwards:
for (int i(v.size()); i > 0; --i)
sum_of_elements += v[i-1];
We can use range-checked "subscripting," counting backwards (just in case):
for (int i(v.size()); i > 0; --i)
sum_of_elements += v.at(i-1);
We can use reverse iterators in a for loop:
for(std::vector<int>::const_reverse_iterator i(v.rbegin()); i != v.rend(); ++i)
sum_of_elements += *i;
We can use forward iterators, iterating backwards, in a for loop (oooh, tricky!):
for(std::vector<int>::const_iterator i(v.end()); i != v.begin(); --i)
sum_of_elements += *(i - 1);
We can use accumulate with reverse iterators:
sum_of_elems = std::accumulate(v.rbegin(), v.rend(), 0);
We can use for_each with a lambda expression using reverse iterators:
std::for_each(v.rbegin(), v.rend(), [&](int n) { sum_of_elements += n; });
So, as you can see, there are just as many ways to sum the vector backwards as there are to sum the vector forwards, and some of these are much more exciting and offer far greater opportunity for off-by-one errors.
#include<boost/range/numeric.hpp>
int sum = boost::accumulate(vector, 0);
One can also use std::valarray<T> like this
#include<iostream>
#include<vector>
#include<valarray>
int main()
{
std::vector<int> seq{ 1,2,3,4,5,6,7,8,9,10 };
std::valarray<int> seq_add{ seq.data(), seq.size() };
std::cout << "sum = " << seq_add.sum() << "\n";
return 0;
}
Some may not find this way efficient since the size of valarray needs to be as big as the size of the vector and initializing valarray will also take time.
In that case, don't use it and take it as yet another way of summing up the sequence.
C++0x only:
vector<int> v; // and fill with data
int sum {}; // or = 0 ... :)
for (int n : v) sum += n;
This is similar to the BOOST_FOREACH mentioned elsewhere and has the same benefit of clarity in more complex situations, compared to stateful functors used with accumulate or for_each.
I'm a Perl user, an a game we have is to find every different ways to increment a variable... that's not really different here. The answer to how many ways to find the sum of the elements of a vector in C++ is probably an infinity...
My 2 cents:
Using BOOST_FOREACH, to get free of the ugly iterator syntax:
sum = 0;
BOOST_FOREACH(int & x, myvector){
sum += x;
}
iterating on indices (really easy to read).
int i, sum = 0;
for (i=0; i<myvector.size(); i++){
sum += myvector[i];
}
This other one is destructive, accessing vector like a stack:
while (!myvector.empty()){
sum+=myvector.back();
myvector.pop_back();
}
#include<iostream>
#include<vector>
#include<numeric>
using namespace std;
int main() {
vector<int> v = {2,7,6,10};
cout<<"Sum of all the elements are:"<<endl;
cout<<accumulate(v.begin(),v.end(),0);
}
Using inclusive_scan (C++17 and above):
The advantage is you can get sums of first "N" elements in a vector. Below is the code. Explanation in comments.
To use inclusive_scan , need to include "numeric" header.
//INPUT VECTOR
std::vector<int> data{ 3, 1, 4, 1, 5, 9, 2, 6 };
//OUTPUT VECTOR WITH SUMS
//FIRST ELEMENT - 3
//SECOND ELEMENT - 3 + 1
//THIRD ELEMENT - 3 + 1 + 4
//FOURTH ELEMENT - 3 + 1 + 4 + 1
// ..
// ..
//LAST ELEMENT - 3 + 1 + 4 + 1 + 5 + 9 + 2 + 6
std::vector<int> sums(data.size());
//SUM ALL NUMBERS IN A GIVEN VECTOR.
inclusive_scan(data.begin(), data.end(),
sums.begin());
//SUM OF FIRST 5 ELEMENTS.
std::cout << "Sum of first 5 elements :: " << sums[4] << std::endl;
//SUM OF ALL ELEMENTS
std::cout << "Sum of all elements :: " << sums[data.size() - 1] << std::endl;
Also there is an overload where the execution policy can be specified. Sequential execution or Parallel execution. Need to include "execution" header.
//SUM ALL NUMBERS IN A GIVEN VECTOR.
inclusive_scan(std::execution::par,data.begin(), data.end(),
sums.begin());
Using reduce :
One more option which I did not notice in the answers is using std::reduce which is introduced in c++17.
But you may notice many compilers not supporting it (Above GCC 10 may be good). But eventually the support will come.
With std::reduce, the advantage comes when using the execution policies. Specifying execution policy is optional. When the execution policy specified is std::execution::par, the algorithm may use hardware parallel processing capabilities. The gain may be more clear when using big size vectors.
Example:
//SAMPLE
std::vector<int> vec = {2,4,6,8,10,12,14,16,18};
//WITHOUT EXECUTION POLICY
int sum = std::reduce(vec.begin(),vec.end());
//TAKING THE ADVANTAGE OF EXECUTION POLICIES
int sum2 = std::reduce(std::execution::par,vec.begin(),vec.end());
std::cout << "Without execution policy " << sum << std::endl;
std::cout << "With execution policy " << sum2 << std::endl;
You need <numeric> header for std::reduce.
And '<execution>' for execution policies.
std::accumulate could have overflow issues so the best approach could be to do range based accumulation on bigger data type variable to avoid overflow issues.
long long sum = 0;
for (const auto &n : vector)
sum += n;
And then downcast to appropriate data type further using static_cast<>.
Nobody seems to address the case of summing elements of a vector that can have NaN values in it, e.g. numerical_limits<double>::quite_NaN()
I usually loop through the elements and bluntly check.
vector<double> x;
//...
size_t n = x.size();
double sum = 0;
for (size_t i = 0; i < n; i++){
sum += (x[i] == x[i] ? x[i] : 0);
}
It's not fancy at all, i.e. no iterators or any other tricks but I this is how I do it. Some times if there are other things to do inside the loop and I want the code to be more readable I write
double val = x[i];
sum += (val == val ? val : 0);
//...
inside the loop and re-use val if needed.
It is easy. C++11 provides an easy way to sum up elements of a vector.
sum = 0;
vector<int> vec = {1,2,3,4,5,....}
for(auto i:vec)
sum+=i;
cout<<" The sum is :: "<<sum<<endl;