How to Sum Up Elements of a C++ Vector

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;

how to select which vector values sum up to a constant

Edit: This is one of my older answers. I wasn't as good back then, and now I know there is a much simpler, faster, and less memory-consuming solution to this problem. If we compute the DP bottom-up in a table that only stores the closest possible sum, we can reconstruct one of the subsets of numbers later using the table values we computed.

This is called a binary knapsack problem. In your case, an object's weight is its value (the number).

If you want a fast solution that runs in O(NW) where N is the number of numbers and W is the target value (can do 10,000 number problems in a fraction of a second), use dynamic programming as in the Wikipedia link. Some other algorithms are also described there.

For a brute force solution that runs in O(N2^N), basically, try all possible combinations of numbers to pick and remember the best one. You can do this with recursion (scroll down to recursivity), or bit operations where you have an integer and each bit of it represents whether to include a number in the set or not, and you simply increment it.

If you have trouble implementing it, here's my code for the fast dynamic programming algorithm:

#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <utility>

using namespace std;

int N, W; //N = number of numbers, W = target sum
vector<int> numbers; //stores the set of numbers

pair<int, multiset<int>> calc(int i, int j) //returns closest sum and best subset of the first i numbers for the target value j
{
static map<pair<int, int>, pair<int, multiset<int>>> dp; //stores results to avoid repeated calculations
pair<int, int> p(i, j); //pair for convenience
if(i == 0) //base case
{
return make_pair(0, multiset<int>(
{}));
}
auto findResult = dp.find(p);
if(findResult != dp.end()) //check if already calculated
{
return findResult->second;
}
auto temp1 = calc(i - 1, j); //compute result if not using number
if(numbers[i - 1] > j) //if current number is too big
{
return temp1;
}
auto temp2 = calc(i - 1, j - numbers[i - 1]); //compute result if using number
temp2.first += numbers[i - 1];
temp2.second.insert(numbers[i - 1]);
pair<int, multiset<int>> result;
if(temp1.first != temp2.first) //compare results and choose best
{
result = temp1.first > temp2.first ? temp1 : temp2;
}
else
{
result = temp1.second.size() < temp2.second.size() ? temp1 : temp2;
}
dp.insert(make_pair(p, result));
return result;
}

int main()
{
cout << "Enter the number of numbers: ";
cin >> N;
cout << "Enter target sum: ";
cin >> W;
numbers.reserve(N); //avoid extra reallocations
cout << "Enter the numbers: ";
for(int i = 0; i < N; i++) //input loop
{
int temp;
cin >> temp;
numbers.push_back(temp);
}
pair<int, multiset<int>> result = calc(N, W); //calculate
//output below
cout << "The best possible sum is " << result.first << ", obtained using the set of numbers {";
if(result.second.size() > 0)
{
cout << *result.second.begin();
for(auto i = ++result.second.begin(); i != result.second.end(); i++)
{
cout << ", " << *i;
}
}
cout << "}.\n";
}

And here is the simple brute force with bit operations (note that this solution can only compute the solution with less than 32 items due to the 32-bit integer used to store the state. Any more takes an extremely long time to run anyways):

#include <iostream>
#include <set>
#include <vector>

using namespace std;

int N, W; //N = number of numbers, W = target sum
vector<int> numbers; //stores the set of numbers

int main()
{
cout << "Enter the number of numbers: ";
cin >> N;
cout << "Enter target sum: ";
cin >> W;
numbers.reserve(N); //avoid extra reallocations
cout << "Enter the numbers: ";
for(int i = 0; i < N; i++) //input loop
{
int temp;
cin >> temp;
numbers.push_back(temp);
}
int bestSum = -1, bestSolution; //stores current best solution
for(unsigned int current = 0; current < (1 << N); current++) //current represents current set
{
int sum = 0;
for(int i = 0; i < N; i++) //compute sum
{
if(current & (1 << i))
{
sum += numbers[i];
}
}
if(sum <= W && sum > bestSum) //update best
{
bestSum = sum;
bestSolution = current;
}
}
multiset<int> result; //make result set for output
int resultSum = 0;
for(int i = 0; i < N; i++)
{
if(bestSolution & (1 << i))
{
result.insert(numbers[i]);
resultSum += numbers[i];
}
}
//output below
cout << "The best possible sum is " << resultSum << ", obtained using the set of numbers {";
if(result.size() > 0)
{
cout << *result.begin();
for(auto i = ++result.begin(); i != result.end(); i++)
{
cout << ", " << *i;
}
}
cout << "}.\n";
}

A solution that outputs all sets of numbers with sum equal to the greatest possible sum not greater than the target value and containing the least possible number of numbers:

#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <utility>

using namespace std;

int N, W; //N = number of numbers, W = target sum
vector<int> numbers; //stores the set of numbers

pair<int, set<multiset<int>>> calc(int i, int j) //returns closest sum and best subset of the first i numbers for the target value j
{
static map<pair<int, int>, pair<int, set<multiset<int>>>> dp; //stores results to avoid repeated calculations
pair<int, int> p(i, j); //pair for convenience
if(i == 0) //base case
{
set<multiset<int>> temp;
temp.emplace();
return make_pair(0, temp);
}
auto findResult = dp.find(p);
if(findResult != dp.end()) //check if already calculated
{
return findResult->second;
}
auto temp1 = calc(i - 1, j); //compute result if not using number
if(numbers[i - 1] > j) //if current number is too big
{
return temp1;
}
pair<int, set<multiset<int>>> temp2 = calc(i - 1, j - numbers[i - 1]), newtemp2; //compute result if using number
newtemp2.first = temp2.first + numbers[i - 1];
for(const auto k : temp2.second)
{
multiset<int> temp = k;
temp.insert(numbers[i - 1]);
newtemp2.second.insert(temp);
}
pair<int, set<multiset<int>>> *result;
if(temp1.first != newtemp2.first) //compare results and choose best
{
result = temp1.first > newtemp2.first ? &temp1 : &newtemp2;
}
else if(temp1.second.begin()->size() != newtemp2.second.begin()->size())
{
result =
temp1.second.begin()->size() < newtemp2.second.begin()->size() ? &temp1 : &newtemp2;
}
else
{
temp1.second.insert(newtemp2.second.begin(), newtemp2.second.end());
result = &temp1;
}
dp.insert(make_pair(p, *result));
return *result;
}

int main()
{
cout << "Enter the number of numbers: ";
cin >> N;
cout << "Enter target sum: ";
cin >> W;
numbers.reserve(N); //avoid extra reallocations
cout << "Enter the numbers: ";
for(int i = 0; i < N; i++) //input loop
{
int temp;
cin >> temp;
numbers.push_back(temp);
}
pair<int, set<multiset<int>>> result = calc(N, W); //calculate
//output below
cout << "The best possible sum is " << result.first << ", which can be obtained using a set of "
<< result.second.begin()->size() << " numbers " << result.second.size()
<< " different ways:\n";
for(const auto &i : result.second)
{
cout << '{';
if(i.size() > 0)
{
cout << *i.begin();
for(auto j = ++i.begin(); j != i.end(); ++j)
{
cout << ", " << *j;
}
}
cout << "}\n";
}
}

Sum elements in vector assembly

mov bx,ax

There's nothing meaningful in AX at this point in the program. The value that you're after is in the suma variable.

Next code will show results provided the sum stays below 100.

mov ah, 09h
lea dx, msg
int 21h

mov al, suma ;Result happens to be 55
aam ;Tens go to AH, units go to AL
or ax, "00" ;Make ASCII characters
mov bx, ax ;Move to safe place

mov ah, 02h
mov dl, BH ;Display tens
int 21h
mov ah, 02h
mov dl, BL ;Display units
int 21h

mov ah, 00h
int 16h ;Wait for a key

Summation by elements of vectors in R

We can use colSums after we rbind the vectors 'a', 'b', and 'c'

 colSums(rbind(a,b,c))
#[1] 15 18 21 24

Or we can place it in a list and use Reduce/+

Reduce(`+`, list(a,b,c))
#[1] 15 18 21 24

I used colSums as + have some limitations when there are NA elements. For example.

 a1 <- c(3, 2, NA, 1)
b1 <- c(5, NA, 3, 2)
a1+b1
#[1] 8 NA NA 3

whereas na.rm argument in colSums can be useful for such conditions.

 colSums(rbind(a1,b1), na.rm=TRUE)
#[1] 8 2 3 3

Even the Reduce approach is not good.

Sum different elements of a vector into a new vector without using a for loop? (R programming)

Without zoo:

n <- 10
xVec <- seq(n)
idx <- seq(1, n-2)
xVec[idx] + 2* xVec[idx+1] - xVec[idx+2]
[1] 2 4 6 8 10 12 14 16

How to sum up an array of integers in C#

Provided that you can use .NET 3.5 (or newer) and LINQ, try

int sum = arr.Sum();

How to assign elements to a vector?

This is wrong

std::vector<int> grader[SIZE];

that's an array of vectors which I'm sure is not what you want

Try this

std::vector<int> grader(SIZE);

That's a vector of size SIZE. Once you've declared your vector in the correct way you can use it exactly like an array.

This is wrong

for (f = 0; f < SIZE; f += 15)
{
for (int i = f + 4; i < i + 3; i++)
{
x = 1 / AC * (A * (grader[i] + grader[i + 3] + grader[i + 6] +
grader[i + 9]) + C * grader[i - 3]);
cout << x << " ";
}
}

when f equals SIZE - 1, i equals f + 4 or SIZE + 3, so grader[i] will be an out-of-bounds access. This would be true whether grader was a vector or an array.

This is wrong

for (int i = f + 4; i < i + 3; i++)

i < i + 3 is always true. So that's clearly not what you intended.

Vectors are easy, your mistakes are either in the syntax, or completely unrelated to vectors.

Sum named vector values where the names are reversed in R

This is tricky. I'd be interested to see a more elegant solution

`row.names<-`(do.call(rbind, Map(function(vec, name) {  
x <- names(vec)
l <- sapply(strsplit(x, ":"), function(y) {
paste0("x", sort(as.numeric(sub("\\D", "", y))), collapse = ":")
})
df <- setNames(as.data.frame(table(rep(l, vec))), c("var", "count"))
df$listNo <- name
df
}, vec = myList, name = names(myList))), NULL)

#> var count listNo
#> 1 x1:x2 3 1
#> 2 x3:x4 1 1
#> 3 x1:x1 1 2
#> 4 x1:x2 3 2
#> 5 x1:x6 2 2
#> 6 x3:x4 1 2
#> 7 x1:x2 1 3
#> 8 x3:x4 6 3
#> 9 x2:x5 2 4

Created on 2022-03-06 by the reprex package (v2.0.1)



Related Topics



Leave a reply



Submit