4

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 を使用して「カウント」インターレーターを渡すことを検討していました...?

4

2 に答える 2

4

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です。

于 2014-09-10T11:57:40.547 に答える
0

別の解決策は、コードの内部を調べて、std::set_intersectionその動作を反映するようにカウンター クラスを実装することです。これは operator++ の使用法に依存し、 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

于 2014-09-10T17:24:07.610 に答える