Using adjacent_find with an iterator ?

Sep 25, 2013 at 5:28pm
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 Sep 25, 2013 at 5:37pm
Sep 25, 2013 at 5:53pm
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
Sep 25, 2013 at 6:00pm
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
Sep 25, 2013 at 6:01pm
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
Sep 25, 2013 at 6:03pm
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 Sep 25, 2013 at 6:04pm
Sep 25, 2013 at 6:18pm
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 :)
Sep 25, 2013 at 6:47pm
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?
Sep 25, 2013 at 7:33pm
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
Sep 25, 2013 at 9:43pm
Yeh I am not really sure how to fix it and I have never used std::count , any suggestions :( ?
Last edited on Sep 25, 2013 at 11:16pm
Topic archived. No new replies allowed.