Using adjacent_find with an iterator ?

Ok I want to be able to not only return when numbers finds a match but i want to know how many times they match. In the case below you will see that it will tell me "10 is a match of numbers" but if numbers; contained 10 , 10 , 10 how can I get it to tell me "there are 3 matches" or as of now tell me "there are 2 matches"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
   std::vector<int> numbers;   //Contains 10,20,10
   std::vector<int>::iterator it;

   //Search numbers for matches
   it = std::adjacent_find (numbers.begin(), numbers.end());
   
   //Tell me if they matched
   if (it!=numbers.end()){
	std::cout << *it << " Is a match of numbers" '\n';
   }
}


I think this is the easiest way of trying to find how many matches there are, also open to any other ideas!
Last edited on
Could you clarify further? Are you looking for the length of the continuous run of equal numbers in an otherwise unsorted sequence (e.g. "70, -1, 10, 10, 10, 20" gives '3') or for the length of a continuous run in a sorted sequence ("-1, 10, 10, 10, 20, 70" gives '3'), or for a total number of matches in an unsorted sequene ("10, -1, 70, 20, 10, 10" gives '3')?
Use of adjacent_find implies the first, but the comment in code ("10, 20, 10") implies the last
Sorry I was just using a basic example! numbers is sorted by size order so the vector would show 10,10,20 , all I want to know is how many duplicates there are inside the vector I sorted them in size order so I could use adjacent find but I am not sure if that is the best way? its working but it doesnt tell me how many duplicates it contains
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    typedef std::vector<int> vec_type;

    vec_type numbers { 10, 10, 20, 20, 20, 30, 30, 30, 40, 30, 10, 10 };
    
    auto it = std::begin(numbers);

    while ((it = std::adjacent_find(it, std::end(numbers))) != std::end(numbers))
    {
        auto value = *it;
        unsigned matches = 1;

        while (++it != std::end(numbers) && *it == value)
            ++matches;
       
        std::cout << value << ": " << matches << " matches.\n" ;
    }
}


http://ideone.com/aZz6vq
if it's sorted, you can find the end of the range in logarithmic time (in the size of the container) using upper_bound:

1
2
3
4
5
6
7
   //Tell me if they matched
   if (it!=numbers.end()){
    std::cout << *it << " Is a match of "
        << std::upper_bound(it, numbers.end(), *it) - it
        << " numbers\n";
   }
}


or run down to the end of it with find_if with linear time in the length of the subsequence
Last edited on
Guys thanks, Cire that works perfectly , its exactly what I needed ! now I can continue with my code but I am going to be spending a while breaking down exactly how it works (really quite new to vectors+iterators) , thanks again really appreciate it :)
Actually just noticed a problem with that Cire.

If the first number is lower than the second two numbers following it , it return "1 match" and shows the low number. Example:

numbers = 5,15,15 . I get a cout of "5: 1 matches". Rather than "15: two matches"

but...

numbers = 5,5,15. I get the correct cout of "5: 2 matches"

so anytime the pair of numbers is greater than the lower single digit , it displays incorrectly using the wrong values, any ideas?
Strange. adjacent_find should return iterator to first 15 in the {5, 15, 15}.

Cubbi wrote:
or run down to the end of it with find_if with linear time in the length of the subsequence

There is also the std::count
Yeh I am not really sure how to fix it and I have never used std::count , any suggestions :( ?
Last edited on
Topic archived. No new replies allowed.