Reputation: 195543
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
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
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
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