Andrej Kesely
Andrej Kesely

Reputation: 195543

Finding not equal adjacent indexes in vector

I have this vector of ints:

std::vector<int> v = {1, 1, 2, 2, 2, 3};

and I want to find indexes, where the adjacent elements aren't equal:

1
4
5

My solution is (which isn't working):

std::vector<int> v = {1, 1, 2, 2, 2, 3};

auto i1 = std::begin(v);

while(1)
{
    i1 = std::adjacent_find(i1, std::end(v), std::not_equal_to<int>());
    std::cout << std::distance(std::begin(v), i1) << '\n';

    if (i1++ == std::end(v))
        break;
}

This prints:

1
4
6

The last elements points to index 6, but I want it to point 5 (value 3). Any help appreciated!

Upvotes: -1

Views: 368

Answers (3)

Vlad from Moscow
Vlad from Moscow

Reputation: 311068

Try the following approach (I renamed i1 to it)

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

int main()
{
    std::vector<int> v = { 1, 1, 2, 2, 2, 3 };

    auto it = std::begin(v);

    do
    {
        it = std::adjacent_find( it, std::end(v), std::not_equal_to<int>());
        if ( it == std::end( v ) ) it = std::prev( it );

        std::cout << std::distance(std::begin(v), it) << '\n';

        std::advance( it, 1 );
    } while ( it  != std::end( v ) );        
}

The program output is

1
4
5

Before calling the do-while loop you should check that the vector is not empty.

For example

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

int main()
{
    std::vector<int> v = { 1, 1, 2, 2, 2, 3 };

    if ( not v.empty() )
    {
        auto it = std::begin(v);

        do
        {
            it = std::adjacent_find( it, std::end(v), std::not_equal_to<int>());
            if ( it == std::end( v ) ) it = std::prev( it );

            std::cout << std::distance(std::begin(v), it) << '\n';

            std::advance( it, 1 );
        } while ( it  != std::end( v ) );
    }        
}

As for your approach then you are trying to output

std::distance(std::begin(v), std::end( v ) )

that is equal to 6 when i1 is equal to std::end( v ).

Upvotes: 1

Marek R
Marek R

Reputation: 38082

Your code and expected answer are invalid. Proper answer for this data is:

1
4

Last iteration of your loop treats result where nothing was found as a valid result. That is why you see size of the array as a last result.

So fixed code looks like this:

std::vector<int> v = {1, 1, 2, 2, 2, 3};

auto i1 = std::begin(v);

while(1)
{
    i1 = std::adjacent_find(i1, std::end(v), std::not_equal_to<int>());
    if (i1 == std::end(v))
        break;

    std::cout << std::distance(std::begin(v), i1) << '\n';
    ++i1;
}

Upvotes: 2

Scott Hunter
Scott Hunter

Reputation: 49893

Assuming it will always treat the last index in this way, you could just subtract 1 from the last value in the otherwise correct result.

Upvotes: 1

Related Questions