2014-09-10 1 views
3

Учитывая 2 комплекта (C++) Есть удобный способ получить размер пересечения без alocations (как станд :: set_intersection делает)размера SetIntersection без выделения

Конечно, я мог бы скопировать реализацию минус назначение но я всегда, а не заново изобретать колесо

int count = 0; 
while (first1!=last1 && first2!=last2) 
{ 
    if (*first1<*first2) ++first1; 
    else if (*first2<*first1) ++first2; 
    else { 
     count++; ++first1; ++first2; 
    } 
} 

Я рассматривал, используя зЬй :: set_intersection и пройти «подсчета» interator ...?

+0

который распределение в станд :: set_intersection вы имеете в виду? – 4pie0

+0

@ 0d0a 'std :: set_intersection 'копирует общие элементы в выходной итератор и обычно требует выделения для контейнера и, возможно, также распределения для копируемых элементов. – hvd

+1

Ваш код выглядит правильно, и именно так я бы это сделал. Вы могли бы построить «счетный» итератор, который не выполняет распределение, но я сомневаюсь, что это будет проще, чем это. – Beta

ответ

4

С некоторой помощью библиотеки подталкивания итератора и 14 C++ в общей лямбде:

#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.

+0

Это выглядит красиво и точно, что я искал. Я проверю его немного и отметю как aswer – user2232888

0

Другое решение может заключаться в том, чтобы заглянуть внутрь в код std::set_intersection и реализовать свой встречный класс, чтобы отразить его поведение. Это зависит от использования оператора ++, std::set_intersection использует префикс, но я добавил также оператор postfix.

#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

Смежные вопросы