在set和map键之间找到set_difference

时间:2013-03-22 20:50:06

标签: c++ map set set-difference

我想问一下是否有可能提供一个示例,说明如何使用set_difference找到地图集和键之间的区别

我知道另一个问题std::set_difference is it possible to compare set and map Keys?,但它指出了另一个没有明确例子的问题。我需要一个不使用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()));

3 个答案:

答案 0 :(得分:7)

您可以使用自定义比较器执行此操作。标准算法使用严格的弱排序。为了测试两个元素的相等性,比较器需要应用两次。当comp(first, second)comp(second, first)都返回false(其中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

}

答案 1 :(得分:0)

@Superlokkus @jrok我知道这篇文章已经晚了一年......仍然希望澄清这个问题。 比较运算符重载时,MS Visual Studio出现问题。问题是有两种组合没有被考虑:

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;
    }
};

通过插入最后两个运算符,我们将插入编译器获取差异所需的所有选项。事实上,我建议使用const int&而不是前两个运算符中提供的int。对于小的情况,这是不相关的,但是当我们有非常大的对,int或甚至更糟的真正大容器的数组时,那么操作将受到内存限制,因为我们将有大量的内存访问。通过使用它,我们传递参数的引用,并且不需要复制参数,因此避免了复制操作并用另一组完全不必要的值填充缓存。

作为最后一点,我发现@jrok提出的第一个解决方案在发布模式(MSVC 2013)中完美编译而不是在调试中是非常奇怪的。很高兴知道为什么!

答案 2 :(得分:0)

我自己对如何编写比较谓词的轻微偏好是:

class KeyLess
{
    public:

      template< typename KeyType >
      static KeyType getKey( const KeyType& k ) 
      {  
          return k;
      }

      template< typename KeyType, typename ValueType >
      static KeyType getKey( std::pair< const KeyType, ValueType > const& p ) 
      {         
          return p.first;
      }

      template< typename L, typename R >
      bool operator()( const L& l, const R& r ) const
      {
          return getKey( l ) < getKey( r );
      }
};

您现在可以在整个代码中使用它。