c++ STL set difference

2019-01-30 17:22发布

Does the C++ STL set data structure have a set difference operator?

10条回答
霸刀☆藐视天下
2楼-- · 2019-01-30 17:51

The chosen answer is correct, but has some syntax errors.

Instead of

#include <algorithms>

use

#include <algorithm>

Instead of

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

use

std::insert_iterator<set<int> >(result, result.end()));
查看更多
可以哭但决不认输i
3楼-- · 2019-01-30 17:53

All of the answers I see here are O(n). Wouldn't this be better?:

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

That seems to do the right thing. I'm not sure how to deal with the case that Compare's type doesn't fully specify its behavior, as in if Compare is a std::function<bool(int,int)>, but aside from that, this seems to work right and should be like O((num overlapping) • log(lhs.size())).

In the case that lhs doesn't contain *i, it's probably possible to optimize further by doing an O(log(rhs.size())) search for the next element of rhs that's >= the next element of lhs. That would optimize the case that lhs = {0, 1000} and rhs = {1, 2, ..., 999} to do the subtraction in log time.

查看更多
The star\"
4楼-- · 2019-01-30 17:54

Not as a method but there's the external algorithm function 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

查看更多
beautiful°
5楼-- · 2019-01-30 17:54

can we just use

 set_difference(set1.begin(), set1.end(), set2.begin(). set2,end(),std::back_inserter(result)).
查看更多
淡お忘
6楼-- · 2019-01-30 18:04

Apparently, it does.

SGI - set_difference

查看更多
我想做一个坏孩纸
7楼-- · 2019-01-30 18:05

Yes there is, it is in <algorithm> and is called: std::set_difference. The usage is:

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

In the end, the set result will contain the s1-s2.

查看更多
登录 后发表回答