Compute the sum of part of the vector using std:: accumulate - c++

Having this vector
vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
how can I compute the sum of the first half of it (which is 15) using the accumulate function?
Can I do this using the for loop with only the iterators (not numerical indexes)?

You can
accumulate(v.begin(), v.begin()+int(v.size()/2), 0)
if v is your vector.
You can also write a loop:
int sum = 0;
for (vector<int>::iterator it = v.begin(); it != v.begin+int(v.size()/2); ++it) {
sum += *it;
}

To work with just the first half you have to get iterators that cover just that range. Usually people want to work with an entire container and so they use begin and end functions, but that's not the only way:
auto begin = std::begin(v);
auto middle = std::begin(v) + v.size()/2; // works for random access iterators
auto middle = begin;
std::advance(middle, v.size()/2);
advance works for input iterators or better, but for input iterators which are not also one of the other types the items that are advanced passed won't be accessible anymore.
auto middle = std::next(begin, v.size()/2); // C++11. works for forward iterators
And these are only a few of the available operations you can perform on the different types of iterators.
So now that you can create iterators that specify your desired range you can use them either in std::accumulate or a manual for loop:
std::accumulate(std::begin(v), std::next(std::begin(v), v.size()/2), 0);
for (auto begin(std::begin(v)), end(begin+v.size()/2); begin!=end; ++begin) {
...
}

accumulate<int>(v.cbegin(), v.cbegin() + v.size()/2, 0);

int sum = std::accumulate(v.begin(), v.begin() + v.size() / 2, 0);

Related

How to Transfer Elements that Match a Predicate from One Vector to Another in C++?

Given two vectors of copyable elements and a predicate over those items, what is an efficient and idiomatic method for:
Removing matching items from the first vector
Appending matching items to the second vector
The following snippet reflects my current thinking, but it does require two passes over the source vector.
vector<int> source{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
vector<int> target;
auto predicate = [](int n) { return n % 2 == 0; };
std::for_each(source.begin(), source.end(), [&predicate, &target](int n) {
if (predicate(n)) {
target.push_back(n);
}
});
auto it = std::remove_if(source.begin(), source.end(), predicate);
source.erase(it, source.end());
I'd use std::partition to partition sourceinto two parts.
auto itr = std::partition(source.begin(), source.end(), predicate);
target.insert(target.end(), itr, source.end());
source.resize(itr - source.begin());
If the ordering needs to remain the same then use stable_partition.
I agree with #acraig5075, that stable_partition, followed by copy and erase will do what you want.
However, if you don't want to shuffle elements around in the source container (probably a futile wish, IMHO), you can do it in a loop: (untested code)
auto itr = source.begin();
while (itr != source.end()) {
if (predicate(*itr)) {
target.push_back(*itr);
itr = source.erase(itr);
} else
++itr;
}
Note that this will "slide down" the elements of elements one at a time as they are moved into target, which is why I opined that avoiding this was probably foolish. (Note: If you're working with list, then it is less foolish)

erase a specific value from a vector array [duplicate]

I'm trying to get a single element from a vector and push it to the back of the vector then remove it so I won't have an empty section in memory. The erase-remove idiom can do this but it removes all instances of a particular value. I just want the first one removed.
I'm not too experienced with standard library algorithms and I can't find the appropriate methods (if any) to do this. Here is an example:
int main() {
std::vector<int> v{1, 2, 3, 3, 4};
remove_first(v, 3);
std::cout << v; // 1, 2, 3, 4
}
So how would I go about removing the first occurance of a 3 from this vector?
Find it first, then erase it:
auto it = std::find(v.begin(),v.end(),3);
// check that there actually is a 3 in our vector
if (it != v.end()) {
v.erase(it);
}
If you don't care about maintaining the ordering of the elements in the vector, you can avoid the copy of the "tail" of remaining elements on erase:
auto it = std::find(v.begin(), v.end(), 3);
if (it != v.end()) {
std::iter_swap(it, v.end() - 1);
v.erase(v.end() - 1);
}

Fast union building of multiple vectors in C++

I’m searching for a fast way to build a union of multiple vectors in C++.
More specifically: I have a collection of vectors (usually 15-20 vectors with several thousand unsigned integers; always sorted and unique so they could also be an std::set). For each stage, I choose some (usually 5-10) of them and build a union vector. Than I save the length of the union vector and choose some other vectors. This will be done for several thousand times. In the end I'm only interested in the length of the shortest union vector.
Small example:
V1: {0, 4, 19, 40}
V2: {2, 4, 8, 9, 19}
V3: {0, 1, 2, 4, 40}
V4: {9, 10}
// The Input Vectors V1, V2 … are always sorted and unique (could also be an std::set)
Choose V1 , V3;
Union Vector = {0, 1, 2, 4, 19, 40} -> Size = 6;
Choose V1, V4;
Union Vector = {0,4, 9, 10, 19 ,40} -> Size = 6;
… and so on …
At the moment I use std::set_union but I’m sure there must be a faster way.
vector< vector<uint64_t>> collection;
vector<uint64_t> chosen;
for(unsigned int i = 0; i<chosen->size(); i++) {
set_union(collection.at(choosen.at(i)).begin(),
collection.at(choosen.at(i)).end(),
unionVector.begin(),
unionVector.end(),
back_inserter(unionVectorTmp));
unionVector.swap(unionVectorTmp);
unionVectorTmp.clear();
}
I'm grateful for every reference.
EDIT 27.04.2017
A new Idea:
unordered_set<unsigned int> unionSet;
unsigned int counter = 0;
for(const auto &sel : selection){
for(const auto &val : sel){
auto r = unionSet.insert(val);
if(r.second){
counter++;
}
}
}
If they're sorted you can roll your own thats O(N+M) in runtime. Otherwise you can use a hashtable with similar runtime
The de facto way in C++98 is set_intersection, but with c++11 (or TR1) you can go for unordered_set, provided the initial vector is sorted, you will have a nice O(N) algorithm.
Construct an unordered_set out of your first vector
Check if the elements of your 2nd vector are in the set
Something like that will do:
std::unordered_set<int> us(std::begin(v1), std::end(v1));
auto res = std::count_if(std::begin(v2), std::end(v2), [&](int n) {return us.find(n) != std::end(us);}
There's no need to create the entire union vector. You can count the number of unique elements among the selected vectors by keeping a list of iterators and comparing/incrementing them appropriately.
Here's the pseudo-code:
int countUnique(const std::vector<std::vector<unsigned int>>& selection)
{
std::vector<std::vector<unsigned int>::const_iterator> iters;
for (const auto& sel : selection) {
iters.push_back(sel.begin());
}
auto atEnd = [&]() -> bool {
// check if all iterators equal end
};
int count = 0;
while (!atEnd()) {
const int min = 0; // find minimum value among iterators
for (size_t i = 0; i < iters.size(); ++i) {
if (iters[i] != selection[i].end() && *iters[i] == min) {
++iters[i];
}
}
++count;
}
return count;
}
This uses the fact that your input vectors are sorted and only contain unique elements.
The idea is to keep an iterator into each selected vector. The minimum value among those iterators is our next unique value in the union vector. Then we increment all iterators whose value is equal to that minimum. We repeat this until all iterators are at the end of the selected vectors.

How do I remove the first occurrence of a value from a vector?

I'm trying to get a single element from a vector and push it to the back of the vector then remove it so I won't have an empty section in memory. The erase-remove idiom can do this but it removes all instances of a particular value. I just want the first one removed.
I'm not too experienced with standard library algorithms and I can't find the appropriate methods (if any) to do this. Here is an example:
int main() {
std::vector<int> v{1, 2, 3, 3, 4};
remove_first(v, 3);
std::cout << v; // 1, 2, 3, 4
}
So how would I go about removing the first occurance of a 3 from this vector?
Find it first, then erase it:
auto it = std::find(v.begin(),v.end(),3);
// check that there actually is a 3 in our vector
if (it != v.end()) {
v.erase(it);
}
If you don't care about maintaining the ordering of the elements in the vector, you can avoid the copy of the "tail" of remaining elements on erase:
auto it = std::find(v.begin(), v.end(), 3);
if (it != v.end()) {
std::iter_swap(it, v.end() - 1);
v.erase(v.end() - 1);
}

How do I remove an item from a stl vector with a certain value?

I was looking at the API documentation for stl vector, and noticed there was no method on the vector class that allowed the removal of an element with a certain value. This seems like a common operation, and it seems odd that there's no built in way to do this.
std::remove does not actually erase elements from the container: it moves the elements to be removed to the end of the container, and returns the new end iterator which can be passed to container_type::erase to do the actual removal of the extra elements that are now at the end of the container:
std::vector<int> vec;
// .. put in some values ..
int int_to_remove = n;
vec.erase(std::remove(vec.begin(), vec.end(), int_to_remove), vec.end());
If you want to remove an item, the following will be a bit more efficient.
std::vector<int> v;
auto it = std::find(v.begin(), v.end(), 5);
if(it != v.end())
v.erase(it);
or you may avoid overhead of moving the items if the order does not matter to you:
std::vector<int> v;
auto it = std::find(v.begin(), v.end(), 5);
if (it != v.end()) {
using std::swap;
// swap the one to be removed with the last element
// and remove the item at the end of the container
// to prevent moving all items after '5' by one
swap(*it, v.back());
v.pop_back();
}
Use the global method std::remove with the begin and end iterator, and then use std::vector.erase to actually remove the elements.
Documentation links
std::remove http://www.cppreference.com/cppalgorithm/remove.html
std::vector.erase http://www.cppreference.com/cppvector/erase.html
std::vector<int> v;
v.push_back(1);
v.push_back(2);
//Vector should contain the elements 1, 2
//Find new end iterator
std::vector<int>::iterator newEnd = std::remove(v.begin(), v.end(), 1);
//Erase the "removed" elements.
v.erase(newEnd, v.end());
//Vector should now only contain 2
Thanks to Jim Buck for pointing out my error.
From c++20:
A non-member function introduced std::erase, which takes the vector and value to be removed as inputs.
ex:
std::vector<int> v = {90,80,70,60,50};
std::erase(v,50);
The other answers cover how to do this well, but I thought I'd also point out that it's not really odd that this isn't in the vector API: it's inefficient, linear search through the vector for the value, followed by a bunch of copying to remove it.
If you're doing this operation intensively, it can be worth considering std::set instead for this reason.
If you have an unsorted vector, then you can simply swap with the last vector element then resize().
With an ordered container, you'll be best off with ‍std::vector::erase(). Note that there is a std::remove() defined in <algorithm>, but that doesn't actually do the erasing. (Read the documentation carefully).
*
C++ community has heard your request :)
*
C++ 20 provides an easy way of doing it now.
It gets as simple as :
#include <vector>
...
vector<int> cnt{5, 0, 2, 8, 0, 7};
std::erase(cnt, 0);
You should check out std::erase and std::erase_if.
Not only will it remove all elements of the value (here '0'), it will do it in O(n) time complexity. Which is the very best you can get.
If your compiler does not support C++ 20, you should use erase-remove idiom:
#include <algorithm>
...
vec.erase(std::remove(vec.begin(), vec.end(), 0), vec.end());
See also std::remove_if to be able to use a predicate...
Here's the example from the link above:
vector<int> V;
V.push_back(1);
V.push_back(4);
V.push_back(2);
V.push_back(8);
V.push_back(5);
V.push_back(7);
copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
// The output is "1 4 2 8 5 7"
vector<int>::iterator new_end =
remove_if(V.begin(), V.end(),
compose1(bind2nd(equal_to<int>(), 0),
bind2nd(modulus<int>(), 2)));
V.erase(new_end, V.end()); [1]
copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
// The output is "1 5 7".
A shorter solution (which doesn't force you to repeat the vector name 4 times) would be to use Boost:
#include <boost/range/algorithm_ext/erase.hpp>
// ...
boost::remove_erase(vec, int_to_remove);
See http://www.boost.org/doc/libs/1_64_0/libs/range/doc/html/range/reference/algorithms/new/remove_erase.html
Two ways are there by which you can use to erase an item particularly.
lets take a vector
std :: vector < int > v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
v.push_back(40);
v.push_back(50);
1) Non efficient way : Although it seems to be quite efficient but it's not because erase function delets the elements and shifts all the elements towards left by 1.
so its complexity will be O(n^2)
std :: vector < int > :: iterator itr = v.begin();
int value = 40;
while ( itr != v.end() )
{
if(*itr == value)
{
v.erase(itr);
}
else
++itr;
}
2) Efficient way ( RECOMMENDED ) : It is also known as ERASE - REMOVE idioms .
std::remove transforms the given range into a range with all the elements that compare not equal to given element shifted to the start of the container.
So, actually don't remove the matched elements.
It just shifted the non matched to starting and gives an iterator to new valid end.
It just requires O(n) complexity.
output of the remove algorithm is :
10 20 30 50 40 50
as return type of remove is iterator to the new end of that range.
template <class ForwardIterator, class T>
ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val);
Now use vector’s erase function to delete elements from the new end to old end of the vector. It requires O(1) time.
v.erase ( std :: remove (v.begin() , v.end() , element ) , v.end () );
so this method work in O(n)
Similar to the erase remove idiom, for vector one could use resize and remove and use iterator distance computation:
std::vector<int> vec;
// .. put in some values ..
int int_to_remove = n;
vec.resize(std::remove(vec.begin(), vec.end(), int_to_remove) - vec.begin());
Tested here.
If you want to do it without any extra includes:
vector<IComponent*> myComponents; //assume it has items in it already.
void RemoveComponent(IComponent* componentToRemove)
{
IComponent* juggler;
if (componentToRemove != NULL)
{
for (int currComponentIndex = 0; currComponentIndex < myComponents.size(); currComponentIndex++)
{
if (componentToRemove == myComponents[currComponentIndex])
{
//Since we don't care about order, swap with the last element, then delete it.
juggler = myComponents[currComponentIndex];
myComponents[currComponentIndex] = myComponents[myComponents.size() - 1];
myComponents[myComponents.size() - 1] = juggler;
//Remove it from memory and let the vector know too.
myComponents.pop_back();
delete juggler;
}
}
}
}