2014-09-10 56 views
3

鑑於2套(C++)是有一種方便的方式來獲得交集的大小沒有任何alocations(如std :: set_intersection一樣)SetIntersection大小,而不分配

當然,我可以複製的執行減去分配但我一直不想重新發明輪子

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

我使用std :: set_intersection並考慮通過一個「計數」迭代符......?

+0

你的意思是它分配的標準:: set_intersection? – 4pie0 2014-09-10 11:46:28

+0

@ 0d0a'std :: set_intersection'將公共元素複製到輸出迭代器中,並且通常需要爲容器分配內存,並且可能還會爲要複製的元素分配內存。 – hvd 2014-09-10 11:52:42

+1

你的代碼看起來是正確的,這就是我要做的。你可能會構建一個「計數」迭代器,它不執行分配,但我懷疑它會比這更簡單。 – Beta 2014-09-10 11:55:57

回答

4

與加速迭代器庫一些幫助和C++ 14的通用Lambda表達式:

#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 2014-09-10 12:06:38

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