2

set_differenceを使用して、マップのセットとキーの違いを見つける方法の例を提供できるかどうかを尋ねたいと思います。

別の質問std::set_differenceで、セットキーとマップキーを比較できることを知っていますか?しかし、それは明確な例のない別の質問を示しています。Boostライブラリを使用しないソリューションが必要です

#include <algorithm>
#include <set>
#include <iterator>
// ...
std::set<int> s1, s2;
// Fill in s1 and s2 with values
std::set<int> result;
std::set_difference(s1.begin(), s1.end(), s2.begin(), s2.end(),
    std::inserter(result, result.end()));
4

3 に答える 3

10

カスタムコンパレーターでそれを行うことができます。標準アルゴリズムは厳密な弱い順序付けを使用します。2 つの要素が等しいかどうかをテストするには、コンパレーターを 2 回適用する必要があります。2 つの要素は、 と が両方ともfalsecomp(first, second)を返す場合に等しくなります (は比較関数です)。比較する要素は異なる型であるため、1 つのコンパレーターでは機能しません。2 つのオーバーロードが必要になります。comp(second, first)comp

struct cmp {
    bool operator()(int i, const std::pair<int, double>& p) const
    {
        return i < p.first;
    }

    bool operator()(const std::pair<int, double>& p, int i) const
    {
        return p.first < i;
    }

};

int main()
{

    std::set<int> s1 { 1, 2, 3, 4 };
    std::map<int, double> s2 { {1, 0}, {2,0}, {4,0} };

    std::set<int> result;

    std::set_difference(s1.begin(), s1.end(), s2.begin(), s2.end(),
        std::inserter(result, result.end()), cmp());

    std::cout << *result.begin(); // will print 3

}
于 2013-03-22T21:13:09.187 に答える
0

@Superlokkus @jrokこの投稿が約1年遅れていることは知っています...それでも、問題を明確にしたいと思います。比較演算子がオーバーロードされている場合、MS Visual Studio に問題があります。問題は、考慮されていない 2 つの組み合わせがあることです。

struct cmp {
    bool operator()(const int& i, const std::pair<int, double>& p) const
    {
        return i < p.first;
    }
    bool operator()(const std::pair<int, double>& p, const int& i) const
    {
        return p.first < i;
    }
    bool operator()(const std::pair<int, double>& p1,
        const std::pair<int, double>& p2) const
    {
        return p1.first < p2.first;
    }
    bool operator()(const int& i1, const int& i2) const
    {
        return i1 < i2;
    }
};

最後の 2 つの演算子を挿入することで、コンパイラが違いを取得するために必要なすべてのオプションを挿入しています。実際、最初の 2 つの演算子で示したconst int&単純なものではなく、を使用することをお勧めします。int小さなケースでは、これは関係ありませんが、ペア、int の非常に大きな配列、またはさらに悪いことに、非常に大きなコンテナーがある場合、多くのメモリ アクセスが発生するため、操作はメモリ バウンドになります。これを使用することで、パラメーターの参照を渡し、パラメーターをコピーする必要がないため、コピー操作を回避し、完全に不要な別の値のセットでキャッシュを埋めることができます。

最後に、@jrok によって提案された最初のソリューションが、デバッグではなくリリース モード (MSVC 2013) で完全にコンパイルされるのは非常に奇妙です。理由がわかってよかったです!

于 2016-12-12T19:23:12.943 に答える