Given an array, suppose we want to replace the $k^\textrm{th}$ entry of the array with $\sum_{i = 0}^k a_i$, or perhaps $\sum_{i = 0}^{k - 1} a_i$; for example, given
int array[10]{ 34, 67, 52, 28, 49, 73, 28, 61, 7, 61 };
The first requirement would give
34, 101, 153, 181, 230, 303, 331, 392, 399, 460
while the second would give
0, 34, 101, 153, 181, 230, 303, 331, 392, 399
If you were to consider using a loop within a loop, this would work, but it would be expensive, especially for very large arrays.
Instead, consdier the following straight-forward implementation:
void partial_sum( double array[], std::size_t capacity ) { for ( std::size_t k{ 1 }; k < capacity; ++k ) { array[k] += array[k - 1]; } }
This requires only a single loop, so its run time will be very fast.
The second problem is a little more difficult to tackle, but here is one possible solution:
double partial_sum( double array[], std::size_t capacity ) { double sum{ 0.0 }; for ( std::size_t k{ 0 }; k < capacity; ++k ) { double tmp{ array[k] }; array[k] = sum; sum += tmp; } return sum; }
This requires two assignments and one addition, so slightly more expensive than the first algorithm, but it is still efficient.
Warning, do not try to reduce the code by using two arithmetic operations, because floating-point arithmetic is not associative, so this may not actually give the best answer, even if it "appears" shorter:
double partial_sum( double array[], std::size_t capacity ) { double sum{ 0.0 }; for ( std::size_t k{ 0 }; k < capacity; ++k ) { sum += array[k]; array[k] = sum - array[k]; } return sum; }
Now that we have seen how we can create a partial sum using the standard library.
#include <iostream> #include <iterator> #include <vector> #include <numeric> template <typename T> std::ostream &operator<<( std::ostream &out, std::vector<T> ); int main() { std::vector<int> vec{ 1,5,3,2,3,4,5,6,3,1,5,2,1,3 }; std::cout << vec << std::endl; std::partial_sum( vec.begin(), vec.end(), vec.begin() ); std::cout << vec << std::endl; return 0; } template <typename T> std::ostream &operator<<( std::ostream &out, std::vector<T> vec ) { out << "{"; if ( !vec.empty() ) { std::copy( vec.begin(), vec.end() - 1, std::ostream_iterator<T>( std::cout, ", " ) ); out << *vec.rbegin(); } return out << "}"; }