Iterating over a vector with std::adjacent_find and custom predicate

1.1k views Asked by At

I am having trouble searching for and printing out pairs of elements in a vector that are separated by 2 from left to right. I need to collect the pairs

The example data that I am operating on is:

std::vector<int> myvector = { 1, 3, 3, 5, 7, 9, 13, 10, 12 };

Given that the std::adjacent_find predicate is:

static const auto gAdjacentPred = [](
    const int& lhs, const int& rhs) {
    std::cout 
        << "(" << lhs << ":" << rhs << ")?" 
        << std::string((rhs == lhs+2)? "true" : "false") 
        << std::endl;
    return (rhs == lhs+2);
};

I was expecting to get the following result (with multiple calls to the predicate along the way):

{1,3}, {3,5}, {5,7}, {7,9} & {10,12}

Ideally thought (and I have no idea how to do this) I would like to merge the values that satisfy the predicate in the middle of the input data ... 3, 5, 7, 9 ... as a single result {3, 9}.

The problem is that I do not really understand how to properly loop over the collection. I did see that std::next(iter) is a trick that I can use to peek ahead at the right most value satisfying the lambda, however this can sometimes point to the end of the collection.

I was expecting that the way I was looping over the data would show multiple calls to the predicate as it iterated over the collection - as it turns out it only calls the predicate function one time (when I assign to the adjIter. Also, in the results I see that the pair 13 & 10 seems to satisfy the predicate. Could someone explain what is going on here as I need to find pairs from left to right that differ by some value - in my case here 2 (with the left side less than the right (I am searching for increasing values from left to right).

(1:3)?true
{1,3}
{3,5}
{7,9}
{13,10}

The problem is that the last pair is also considered

static const auto gAdjacentPred = [](
    const int& lhs, const int& rhs) {
    std::cout 
        << "(" << lhs << ":" << rhs << ")?" 
        << std::string((rhs == lhs+2)? "true" : "false") 
        << std::endl;
    return (rhs == lhs+2);
};

std::vector<int> myvector = { 1, 3, 3, 5, 7, 9, 13, 10, 12 };
auto adjIter = std::adjacent_find (
    myvector.begin(), myvector.end(), 
    gAdjacentPred);
while (adjIter != myvector.cend()) {        
    auto second = std::next(adjIter);
    // print both sides
    if (second != myvector.cend()) {
        std::cout << "{" << *adjIter << "," << *second << "}" << std::endl;
        adjIter +=2;
    } else {
        adjIter++;
    }
}    
0

There are 0 answers