C ++ STL设置差异


Answers:


135

是的,它在里面<algorithm>,叫做:std::set_difference。用法是:

#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()));

最后,集合result将包含s1-s2


+1。可悲的是,当我需要它时,我放弃了自己的循环:(
peterchen

45
顺便说一句,如果您在非关联容器类上使用set_difference,例如说一个向量,请确保首先对两个容器中的元素进行排序...
paxos1977 08/11/13

4
#include <algorithms>->没有这样的文件,应该是<algorithm>吗?
stefanB

对于set <string>,我必须限定std :: insert_iterator <set <string >>(...)
stefanB

@stefanB:第一个评论是正确的,而第二个评论:常用的是std::inserter代替。由于这是一项功能,因此不需要资格认证。
rlbond

11

是的,算法标头中有一个set_difference函数。

编辑:

仅供参考,设置数据结构能够有效地使用该算法,如其文档中所述。该算法不仅适用于集合,还适用于排序集合上的任何一对迭代器。

正如其他人提到的那样,这是一种外部算法,而不是一种方法。大概适合您的应用程序。


1
它可用于任何一对已排序的容器。
xtofl


2

选择的答案是正确的,但是有一些语法错误。

代替

#include <algorithms>

采用

#include <algorithm>

代替

std::insert_iterator(result, result.end()));

采用

std::insert_iterator<set<int> >(result, result.end()));

9
或仅使用std::inserter(result, result.end())
rlbond

2

再一次,助您一臂之力:

#include <string>
#include <set>
#include <boost/range/algorithm/set_algorithm.hpp>

std::set<std::string> set0, set1, setDifference;
boost::set_difference(set0, set1, std::inserter(setDifference, setDifference.begin());

setDifference将包含set0-set1。


2

C ++没有定义集差值运算符,但是您可以定义自己的(使用其他响应中给出的代码):

template<class T>
set<T> operator -(set<T> reference, set<T> items_to_remove)
{
    set<T> result;
    std::set_difference(
        reference.begin(), reference.end(),
        items_to_remove.begin(), items_to_remove.end(),
        std::inserter(result, result.end()));
    return result;
}

1

不是作为一种方法,而是有外部算法功能set_difference

template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
                              InputIterator2 first2, InputIterator2 last2,
                              OutputIterator result);

http://www.sgi.com/tech/stl/set_difference.html



1

我在这里看到的所有答案都是O(n)。这会更好吗?:

template <class Key, class Compare, class Allocator>   
std::set<Key, Compare, Allocator> 
set_subtract(std::set<Key, Compare, Allocator>&& lhs,
             const std::set<Key, Compare, Allocator>& rhs) {
    if (lhs.empty()) { return lhs; }
    // First narrow down the overlapping range:
    const auto rhsbeg = rhs.lower_bound(*lhs.begin());
    const auto rhsend = rhs.upper_bound(*lhs.rbegin());
    for (auto i = rhsbeg; i != rhsend; ++i) {
        lhs.erase(*i);
    }
    return std::move(lhs);
}

这似乎是对的。我不确定该如何处理Compare类型不是完全指定其行为的情况,例如Comparea std::function<bool(int,int)>,但除此之外,这似乎行之有效,应该像O((num overlay)• log(lhs.size()))。

lhs不包含这种情况的情况下,*i可以通过执行O(log(rhs.size()))搜索rhs>的下一个元素来进一步优化lhs。这将优化这种情况lhs = {0, 1000}rhs = {1, 2, ..., 999}在对数时间中进行减法。


-1

我们可以使用吗

 set_difference(set1.begin(), set1.end(), set2.begin(). set2,end(),std::back_inserter(result)).

4
std::back_inserterpush_back()在目标容器上需要方法result。如果resultstd::set
Attila,2013年

1
请不要在问题中提出问题。
user650261
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.