SetIntersection size без выделения

Учитывая 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 и передать «подсчет» интегратор …?

3

Решение

С некоторой помощью библиотеки 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,

4

Другие решения

Другим решением может быть заглянуть внутрь 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
}

http://ideone.com/j8GrBB

0

По вопросам рекламы [email protected]