Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get all positions of elements in STL vector that are greater than a value

Tags:

c++

std

stl

vector

I would like to know how can I find the index positions of elements that verify a certain condition (for example greater than). For example if I have a vector of int values

vector<int> V;

V contains the values 3 2 5 8 2 1 10 4 7

and I want to get all the index positions of elements that are greater than 5. I know std::find_if but according to the documentation it just finds the first element that satisfies a condition.

like image 771
saloua Avatar asked Oct 20 '12 15:10

saloua


2 Answers

I think I'd use std::copy_if:

std::vector<int> x{3, 2, 5, 8, 2, 1, 10, 4, 7};
std::vector<size_t> y(x.size());

std::iota(y.begin(), y.end(), 0);
std::copy_if(y.begin(), y.end(), 
             std::ostream_iterator<size_t>(std::cout, " "), 
             [&](size_t i) { return x[i] > 5; });

For me, this gives 3 6 8, the indices of 8, 10 and 7 in x -- exactly what we want.

If you're stuck with a C++98/03 compiler/library, you'll use std::remove_copy_if instead (and reverse the sense of the comparison). In this case, you obviously won't be able to use a lambda for the comparison either.

like image 122
Jerry Coffin Avatar answered Oct 25 '22 01:10

Jerry Coffin


Just for fun, transform_if algorithm:

#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>

template<typename InputIterator, typename OutputIterator,
    typename UnaryPredicate, typename UnaryFunction>
OutputIterator
transform_if (InputIterator first, InputIterator last,
    OutputIterator result, UnaryPredicate pred,
    UnaryFunction func)
{
    for (; first != last; ++first, ++result)
        if (pred(*first))
            *result = func(*first);
    return result;
}

int main()
{
    std::vector<int> x {3, 2, 5, 8, 2, 1, 10, 4, 7};
    std::vector<size_t> indices;

    size_t index = 0;
    transform_if(x.begin(), x.end(), std::back_inserter(indices),
        [&](int i){ return ++index, i > 5; },
        [&](int){ return index-1; });

    std::copy(indices.begin(), indices.end(),
              std::ostream_iterator<size_t>(std::cout, " "));
}

Output: 3 6 8

like image 41
jrok Avatar answered Oct 25 '22 02:10

jrok