c++ STL set difference

后端 未结 10 1689
梦如初夏
梦如初夏 2020-12-23 11:05

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

相关标签:
10条回答
  • 2020-12-23 11:57

    Apparently, it does.

    SGI - set_difference

    0 讨论(0)
  • 2020-12-23 11:58

    C++ does not define a set difference operator but you can define your own (using code given in other responses):

    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;
    }
    
    0 讨论(0)
  • 2020-12-23 11:58

    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

    0 讨论(0)
  • 2020-12-23 11:58

    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.

    0 讨论(0)
提交回复
热议问题