SetIntersection size without selection
For two sets (C ++) there is a convenient way to get the size of the intersection without any allocations (as std :: set_intersection does)
Of course, I could copy the implementation minus the assignment, but I always prefer not to reinvent the wheel
int count = 0;
while (first1!=last1 && first2!=last2)
{
if (*first1<*first2) ++first1;
else if (*first2<*first1) ++first2;
else {
count++; ++first1; ++first2;
}
}
I was considering using std :: set_intersection and passing a "counting" interner ...?
source to share
With Boost Iterator library and C ++ 14 generic lambdas:
#include <set>
#include <algorithm>
#include <iostream>
#include <boost/function_output_iterator.hpp>
int main()
{
std::set<int> s1 { 1,2,3,4 };
std::set<int> s2 { 3,4,5,6 };
int i = 0;
auto counter = [&i](auto){ ++i; }; // C++14
// auto counter = [&i](int ){ ++1; }; // C++11
// pre C++11, you'd need a class with overloaded operator()
std::set_intersection(
s1.begin(), s1.end(), s2.begin(), s2.end(),
boost::make_function_output_iterator(counter)
);
std::cout << i;
}
Conclusion 2
.
source to share
Another solution might be to look inside the code std::set_intersection
and implement your counter class to reflect its behavior. It depends on the use of the ++ operator, std::set_intersection
uses the prefix, but I added the postfix operator as well.
#include <set>
#include <algorithm>
#include <iostream>
class CountIt {
public:
CountIt() : storage(0), counter(0) {}
CountIt& operator++()
{
++counter;
return *this;
}
CountIt operator++(int)
{
CountIt oldValue = *this;
return ++( *this);
}
int& operator*() { return storage;}
int storage, counter;
};
int main()
{
std::set<int> s1 { 1,2,3,4 };
std::set<int> s2 { 3,4,5,6 };
CountIt const & c = std::set_intersection(
s1.begin(), s1.end(), s2.begin(), s2.end(),
CountIt()
);
std::cout << c.counter; // 2, hopefuly
}
source to share