Reputation: 1073
The set_difference algorithm gives you output of elements which are in the first range and not in second. Is there a algorithm which will just give me the count and not the difference.
I understand I can implement my own version of the algorithm described in the link or I can count the number of elements after I get the result. Is there a existing API which will do it for me efficiently.
Thanks
Upvotes: 1
Views: 533
Reputation: 302757
You could simply write your own OutputIterator-like thing that you could pass into std::set_difference
. An OutputIterator needs to be dereferencable, assignable, and incrementable. Note also that std::set_difference
returns an OutputIterator, so we can take advantage of that by making it convertible to int
.
Hence something like:
struct CountingIterator
: std::iterator<std::output_iterator_tag, int>
{
template <typename T>
CountingIterator& operator=(T&& ) {
++count;
return *this;
}
CountingIterator& operator*() { return *this; }
CountingIterator& operator++() { return *this; }
operator int() { return count; }
int count = 0;
};
Which, when modifying the example in std::set_difference
yields:
int main() {
std::vector<int> v1 {1, 2, 5, 5, 5, 9};
std::vector<int> v2 {2, 5, 7};
int count =
std::set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(),
CountingIterator());
std::cout << count << std::endl; // prints 4
}
Upvotes: 1
Reputation: 217135
You may create an "CountingIterator
" as OutputIterator
, something like:
struct CountingIterator
{
CountingIterator& operator*() { return *this; }
CountingIterator& operator ++() { return *this; }
CountingIterator& operator ++(int) { return *this; }
template <typename T>
CountingIterator& operator =(const T&) { ++counter; return *this; }
int counter = 0;
};
Upvotes: 0
Reputation: 133567
It's an operation such trivial that doesn't require a specific method. If you can't afford to allocate a temporary set to compute the difference and then get their size, just compute it with std::accumulate
or std::for_each
:
unordered_set<int> set1 = {1,2,3,4,5};
unordered_set<int> set2 = {2,4,6};
size_t count = set1.size() - std::accumulate(set1.begin(), set1.end(), 0, [&set2](size_t previous, int value) { return set2.count(value) + previous; });
But if you don't have any specific requirement or huge sets doing set_difference
+ size()
is just fine.
Upvotes: 0