Учитывая 2 набора (C ++), есть удобный способ получить размер пересечения без каких-либо размещений (как это делает std :: set_intersection)
Конечно, я мог бы скопировать реализацию без назначения, но я всегда предпочитаю не изобретать велосипед
int count = 0;
while (first1!=last1 && first2!=last2)
{
if (*first1<*first2) ++first1;
else if (*first2<*first1) ++first2;
else {
count++; ++first1; ++first2;
}
}
Я думал об использовании std :: set_intersection и передать «подсчет» интегратор …?
С некоторой помощью библиотеки Boost Iterator и общих лямбд в C ++ 14:
#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;
}
Выход 2
,
Другим решением может быть заглянуть внутрь std::set_intersection
код и реализовать свой класс счетчика, чтобы отразить его поведение. Это зависит от использования оператора ++, std::set_intersection
использует префикс, но я добавил также постфиксный оператор.
#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
}